我在 Powershell 中使用以下脚本(版本为 5.1):
Get-Content -Path path\to\text\file\to\be\read.txt -Wait
现在,即使文件没有更新,它也会继续读取。
在文本文件中找到特定行后如何停止?
有没有其他方法可以在条件下阻止这种情况?
最佳答案
tl;博士
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
operator使用正则表达式 ( about_Regular_Expressions
) 执行子字符串匹配。继续阅读以了解为什么要使用假人
do
需要循环。Paxz's answer是在正确的轨道上,但是 它尝试使用
break
(孤立地)退出管道,这(通常)终止整个脚本 (如果您以交互方式将管道作为单个命令提交,您可能不会注意到)。break
/continue
旨在退出/继续循环(for
、foreach
、do
、while
和 switch
语句[1]),而不是管道 .从 PowerShell [Core] 7.2.2 开始,没有直接的方法可以提前退出管道 ,尽管添加此功能是 this long-standing feature request on GitHub 的主题;目前只能直接使用
Select-Object
与 -First
可以通过使用非公共(public)异常提前退出管道;而return
可用于 ForEach-Object
脚本 block ,它只退出当前脚本 block 调用,同时继续处理额外的管道输入。如果您使用
break
或 continue
, PowerShell 将查找任何封闭循环,如果没有,则整个脚本退出。 但是,如果您在管道周围包裹一个虚拟循环 [2],如上所示 - 其唯一目的是为
break
提供一些东西突破- 执行继续,如(通常)所希望的 .警告 :
break
/continue
(和 throw
)有一个重要的副作用 : 他们不要让参与管道的其他命令有机会正常退出 ;也就是说,他们的end
block /EndProcessing()
方法没有被调用,这可能在两个方面存在问题:Select-Object -First
。使用高级 PowerShell 函数/脚本(但不使用(二进制)cmdlet,它可以通过实现 System.IDisposable
接口(interface)来确保清理),如 GitHub issue #7930 中所述; GitHub PR #9900旨在解决这个问题,引入一个专用的 cleanup
堵塞。 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
too 立即退出语句,不处理数组中的其他元素; continue
相比之下,继续处理下一个元素。[2] 另一种选择是使用
throw
通过将管道包含在 try
/ catch
statement 中来生成脚本终止错误,如this answer所示.但是,这有在自动 $Error
中记录条目的副作用。收集,即使在概念上没有发生实际错误。
关于powershell - 使用powershell在文本文件中找到特定行后如何停止Get-Content -wait?按需退出管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51981048/