Вопрос или проблема
Я работаю над скриптом PowerShell для поиска оффлайн-устройств и ежедневной отправки списка пользователям по электронной почте. Я почти завершил скрипт, за исключением одной части. Я выводю внутренний текст с веб-сайта в текстовый файл, затем использую PowerShell для анализа этого текстового файла и извлекаю строки, содержащие ряд определенных строк. Содержимое текстового файла будет в следующем формате:
Область: 15NT_ Комната: Rm_42 Адрес: 3 Тип: CL41 – Проблемы надзора:
Адрес: 2 Тип: Bed1P – ОФФЛАЙН Надзор:
Адрес: 3 Тип: Bed2 – Отсутствует FB-модуль Надзор:
Адрес: 4 Тип: ПК – ОФФЛАЙН Надзор:
Для приведенного выше текста 2 строки содержат строку “ОФФЛАЙН”, которая является одной из строк, которые я ищу. Для приведенного выше текста я хотел бы, чтобы скрипт извлек последнюю строку со строкой “ОФФЛАЙН” и все предыдущие строки, вплоть до и включая строку, начинающуюся со строки “Область”, а затем добавил эти строки в текстовый файл.
Правка: Вот оригинальный код, который я использовал:
$log = get-content C:\temp\RGS.txt
foreach ($line in $log) {
if ($line -like "*Область*" -OR $line -like "*отсутствует*" -or $line -like
"*ОФФЛАЙН*" -or $line -like "*внутренний*" -or $line -like "*конфигурация*" - or $line -like "*неизвестный*") {
$line | out-file -FilePath "C:\temp\RGS Extract.txt" -Append
}
}
Также в исходном тексте будет несколько строк, которые начинаются со слова “Область”, но под которыми не будет указано “Адрес” перед следующей “Областью”. Я не хочу, чтобы эти строки извлекались, так как область не имеет адресов, содержащих одно из ключевых слов, которые я ищу. В основном, всякий раз, когда строка начинается с “Адрес” и содержит одно из ключевых слов, я хотел бы добавить эту строку и все предыдущие строки, вплоть до и включая строку с первым вхождением слова “Область”.
Вот больший образец источника данных, с которым я работаю:
Область: 7NT_ Комната: RM_11 Адрес: 26 Тип: CL41 - Проблемы Надзора:
Адрес: 2 Тип: Bed1P - ОФФЛАЙН Надзор:
Адрес: 3 Тип: Bed2 - Отсутствует FB-модуль Надзор:
Адрес: 6 Тип: PCAudio Надзор:
Адрес: 7 Тип: ПК Надзор:
Адрес: 12 Тип: PB2C Надзор:
Адрес: 15 Тип: Jack2 Надзор:
Область: 7NT_ Комната: Nourish_7116 Адрес: 27 Тип: CL0 Надзор:
Адрес: 4 Тип: Дежурный Надзор:
Область: 7NT_ Комната: Rm_09 Адрес: 28 Тип: CL41 - Проблемы Надзора:
Адрес: 2 Тип: Bed1P - ОФФЛАЙН Надзор:
Адрес: 3 Тип: Bed2 - Отсутствует FB-модуль Надзор:
Адрес: 6 Тип: PCAudio Надзор:
Адрес: 7 Тип: ПК Надзор:
Адрес: 12 Тип: PB2C Надзор:
Адрес: 15 Тип: Jack2 Надзор:
Область: 7NT_ Комната: Rm_12 Адрес: 29 Тип: CL41 - Проблемы Надзора:
Адрес: 2 Тип: Bed1P - ОФФЛАЙН Надзор:
Адрес: 3 Тип: Bed2 - Отсутствует FB-модуль Надзор:
Адрес: 6 Тип: PCAudio Надзор:
Адрес: 7 Тип: ПК Надзор:
Адрес: 12 Тип: PB2C Надзор:
Адрес: 15 Тип: Jack2 Надзор:
Область: 7NT_ Комната: Rm_07 Адрес: 30 Тип: CL41 - Проблемы Надзора:
Адрес: 2 Тип: Bed1P - ОФФЛАЙН Надзор:
Адрес: 3 Тип: Bed2 - Отсутствует FB-модуль Надзор:
Адрес: 6 Тип: PCAudio Надзор:
Адрес: 7 Тип: ПК Надзор:
Адрес: 12 Тип: PB2C Надзор:
Адрес: 15 Тип: Jack2 Надзор:
Область: 7NT_ Комната: Rm_10 Адрес: 31 Тип: CL41 - Проблемы Надзора:
Адрес: 2 Тип: Bed1P - ОФФЛАЙН Надзор:
Адрес: 3 Тип: Bed2 - Отсутствует FB-модуль Надзор:
Адрес: 6 Тип: PCAudio Надзор:
Адрес: 7 Тип: ПК Надзор:
Адрес: 12 Тип: PB2C Надзор:
Адрес: 15 Тип: Jack2 Надзор:
Область: 7NT_ Комната: Med_7108 Адрес: 32 Тип: CL0 Надзор:
Адрес: 4 Тип: Дежурный Надзор:
Для приведенного выше фрагмента, что я хотел бы, чтобы PowerShell вывел в файл, это:
Область: 7NT_ Комната: RM_11 Адрес: 26 Тип: CL41 - Проблемы Надзора:
Адрес: 2 Тип: Bed1P - ОФФЛАЙН Надзор:
Адрес: 3 Тип: Bed2 - Отсутствует FB-модуль Надзор:
Область: 7NT_ Комната: Rm_09 Адрес: 28 Тип: CL41 - Проблемы Надзора:
Адрес: 2 Тип: Bed1P - ОФФЛАЙН Надзор:
Адрес: 3 Тип: Bed2 - Отсутствует FB-модуль Надзор:
Область: 7NT_ Комната: Rm_12 Адрес: 29 Тип: CL41 - Проблемы Надзора:
Адрес: 2 Тип: Bed1P - ОФФЛАЙН Надзор:
Адрес: 3 Тип: Bed2 - Отсутствует FB-модуль Надзор:
Область: 7NT_ Комната: Rm_07 Адрес: 30 Тип: CL41 - Проблемы Надзора:
Адрес: 2 Тип: Bed1P - ОФФЛАЙН Надзор:
Адрес: 3 Тип: Bed2 - Отсутствует FB-модуль Надзор:
Область: 7NT_ Комната: Rm_10 Адрес: 31 Тип: CL41 - Проблемы Надзора:
Адрес: 2 Тип: Bed1P - ОФФЛАЙН Надзор:
Адрес: 3 Тип: Bed2 - Отсутствует FB-модуль Надзор:
Всякий раз, когда строка, начинающаяся с Адрес, содержит одну из фраз, которые я ищу (оффлайн, отсутствие, внутренний, конфигурация), я хотел бы, чтобы эта строка отображалась И первая строка, начинающаяся с Область, выше строки Адрес. Если строка Область идентична для нескольких строк Адрес, тогда я хотел бы, чтобы она отображалась только один раз.
В исходном HTML-файле, из которого я создаю текстовый файл, строки Область всегда помечены тегом h4, а строки Адрес всегда помечены тегом h5, поэтому с точки зрения HTML, если строка h5 содержит одно из ключевых слов, я хотел бы экспортировать ее в текстовый файл вместе с первой строкой h4 перед ней.
Вы можете использовать это:
((gc "filepath.txt")|select-string -pattern "^Область") >>"output.txt"
([array]::reverse((gc "filepath.txt"))|select-string -pattern ".*ОФФЛАЙН.*") >>"output.txt"
Ответ или решение
Для эффективного поиска и извлечения строк из текстового файла с использованием PowerShell, а также формирования отчётов о некорректной работе устройств, предлагаю воспользоваться следующим подходом. Мы будем искать строки, содержащие заданные ключевые слова, и извлекать соответствующие строки и предыдущие строки, чтобы сформировать вывод для отчёта.
Задача
Вам необходимо извлечь строки из текстового файла, содержащие ключевые слова, такие как "OFFLINE", "missing", и сопоставить их с первой строкой, начинающейся со слова "Area", для формирования отчёта.
Решение
Вы можете использовать следующий PowerShell-скрипт:
# Укажите путь к входному текстовому файлу и к файлу для вывода
$inputFile = "C:\temp\RGS.txt"
$outputFile = "C:\temp\RGS_Extract.txt"
# Получаем весь контент файла
$content = Get-Content -Path $inputFile
# Объявляем массив для хранения данных для вывода
$result = @()
# Инициализируем переменные
$currentArea = ""
$isAreaProcessed = $false
foreach ($line in $content) {
# Проверяем, если строка начинается с "Area"
if ($line -like "Area:*") {
if ($isAreaProcessed -and $currentArea -ne "") {
# Сохраняем текущую область, если она уже была обработана
$result += $currentArea
$result += ""
}
# Обновляем переменную текущей области
$currentArea = $line
$isAreaProcessed = $false
}
# Проверяем наличие ключевых слов в строке
if ($line -match "OFFLINE|missing|internal|configuration") {
$result += $line
$isAreaProcessed = $true
}
}
# Удаляем дубликаты областей
$result = $result | Select-Object -Unique
# Записываем результат в выходной файл
$result | Out-File -FilePath $outputFile -Encoding UTF8
Пояснение к коду
- Исходные данные: Вы задаете путь к файлу, который необходимо анализировать, и куда сохранить результаты.
- Чтение файла:
Get-Content
загружает все строки из текстового файла в массив$content
. - Анализ строк:
- Скрипт проходит по каждой строке, проверяя, начинается ли она с "Area". Если да, мы сохраняем её как текущую область.
- Если встречается строка с ключевыми словами, она добавляется к результату, вместе с текущей областью, если она была установлена.
- Удаление дубликатов: Мы используем
Select-Object -Unique
, чтобы избежать повторяющихся строк области. - Запись результатов: Наконец, отформатированные строки записываются в выходной файл с помощью
Out-File
.
Заключение
Данный подход позволит вам формировать отчёты о состоянии устройств с минимальными усилиями. Вы легко сможете модифицировать ключевые слова или форматы строк в зависимости от условий задачи. С помощью PowerShell вы имеете возможность автоматизировать процесс сбора данных о статусе ваших устройств, что значительно упростит процедуру мониторинга и отчётности.
Если вам нужна дополнительная помощь или уточнения, не стесняйтесь обращаться!