Как остановить Get-Content -wit после того, как я найду определенную строку в текстовом файле, используя powershell?
Я использую этот скрипт ниже в Powershell (версия 5.1):
Get-Content -Path path\to\text\file\to\be\read.txt -Wait
Теперь это продолжает читать даже после того, как файл не получает обновления. Как я могу остановиться после того, как найду определенную строку в текстовом файле? Есть ли другой способ остановить это при условии?
1 ответ
Вы можете передать вывод и использовать foreach для проверки каждой строки, если строка равна определенной строке, которую вы можете использовать break
остановить команду:
Get-Content path\to\text\file\to\be\read.txt -wait | % {$_ ; if($_ -eq "yourkeyword") {break}}
Например, если вы запустите команду выше и сделаете следующее в другой оболочке:
"yourkeyword" | Out-File path\to\text\file\to\be\read.txt -Append
Get-Content
отображает новую строку и останавливается.
Объяснение:
| %
- строка foreach, которая находится в файле или добавляется в файл во время выполнения функции
$_;
- сначала выписать строку foreach, затем выполнить другую команду
if($_ -eq "yourkeyword") {break}
- если строка foreach равна желаемому ключевому слову / строке, остановите Get-Content
tl;dr
do {
Get-Content -Path path\to\text\file\to\be\read.txt -Wait | ForEach-Object {
# Pass the input line through.
$_
# Exit once the string of interest is found.
if ($_ -match 'patternOfInterest') { break }
}
} while ($false) # dummy loop so that `break` can be used.
# NOTE: Without the dummy `do` loop, this code would not be reached.
'Line of interest found.'
Обратите внимание, что -match
Оператор выполняет сопоставление подстроки с помощью регулярных выражений ( about_Regular_Expressions
).
Читайте, почему манекен do
петля нужна.
Ответ Paxz на правильном пути, но он пытается использоватьbreak
(изолированно) для выхода из конвейера, который (обычно) завершает весь сценарий (если вы отправляете конвейер как одну команду в интерактивном режиме, вы можете не заметить).
break
/ continue
предназначены для выхода / продолжения циклов (for
, foreach
, do
, while
, а также switch
заявления [1]), а не конвейеры.
В PowerShell [Core] 7.0 нет прямого способа преждевременно выйти из конвейера, хотя добавление этой функции является предметом этого давнего запроса на функцию на GitHub; в настоящее время только прямое использованиеSelect-Object
с участием -First
может преждевременно выйти из конвейера из-за использования закрытого исключения; покаreturn
может использоваться в ForEach-Object
блок сценария, он только завершает вызов текущего блока сценария, продолжая обрабатывать дополнительный ввод конвейера.
Если вы используете break
или continue
, PowerShell будет искать любой закрывающий цикл, и если его нет, скрипт завершит работу.
Однако, если вы обернете свой конвейер [2]фиктивным циклом, как показано выше, единственная цель которого - предоставить что-то дляbreak
вырваться из - исполнение продолжается, как (обычно) желательно.
Предупреждение:
break
/ continue
(а также throw
) имеют важный побочный эффект: они не дают другим командам, участвующим в конвейере, нормально завершиться; то есть ихend
блоки / EndProcessing()
методы не вызываются, что может быть проблематичным по двум причинам:
Командлеты, которым необходимо очистить (удалить) временно заблокированные ресурсы , не могут быть очищены.
Командлеты агрегирования - те, которые по необходимости собирают весь ввод, прежде чем смогут произвести вывод, - никогда не производят вывод; вот простой пример:
PS> do { 5..1 | % { $_; if ($_ -eq 3) { break } } | Sort-Object } while ($false)
# !! NO OUTPUT, because Sort-Object's EndProcessing() method was never called.
[1] Когда вы исследуете одно значение с switch
заявление, break
выходит из оператора, как и следовало ожидать. Если обрабатывается массив (набор) значений,break
также немедленно выходит из оператора, не обрабатывая дальнейшие элементы в массиве;continue
, напротив, продолжает обработку следующего элемента.
[2] Другой вариант - использовать throw
для генерации ошибки завершения сценария, которую вы поймаете, заключив конвейер в try
/ catch
заявление, как показано в этом ответе. Однако это имеет побочный эффект записи записи в автоматическом$Error
коллекции, даже если концептуально реальной ошибки не произошло.