Rav*_*rma 3 powershell pipeline break powershell-5.0
我在 Powershell 中使用以下脚本(版本为 5.1):
Get-Content -Path path\to\text\file\to\be\read.txt -Wait
Run Code Online (Sandbox Code Playgroud)
现在,即使文件没有更新,它也会继续读取。在文本文件中找到特定行后如何停止?有没有其他方法可以阻止这种情况?
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.'
Run Code Online (Sandbox Code Playgroud)
请注意,-match
运算符使用正则表达式( )执行子字符串匹配。about_Regular_Expressions
继续阅读为什么do
需要虚拟循环。
Paxz 的答案在正确的轨道上,但它尝试使用break
(孤立地)退出管道,这(通常)会终止整个脚本(如果您以交互方式将管道作为单个命令提交,您可能不会注意到)。
break
/continue
旨在退出/继续循环(for
, foreach
, do
, while
, 和switch
statements [1]),而不是管道。
从 PowerShell [Core] 7.0 开始,没有直接的方法可以提前退出管道,尽管添加此功能是GitHub 上这一长期功能请求的主题;目前,只有直接使用Select-Object
with-First
才能通过使用非公共异常提前退出管道;虽然return
可以在ForEach-Object
脚本块中使用,但它只退出当前的脚本块调用,同时继续处理其他管道输入。
如果您使用break
or continue
,PowerShell 将查找任何封闭循环,如果没有,则脚本作为一个整体退出。
然而,如果你在你的管道[2]周围包裹一个虚拟循环,如上所示 - 其唯一目的是提供一些东西break
来打破 -执行继续,如(通常)所希望的。
警告:
break
/ continue
(和throw
)有一个重要的副作用:它们不给参与管道的其他命令一个正常退出的机会;也就是说,它们的end
块/EndProcessing()
方法没有被调用,这可能在两个方面存在问题:
需要清理(处置)临时持有的资源的 Cmdlet无法进行清理。
Select-Object -First
高级 PowerShell 函数/脚本(但不适用于(二进制)cmdlet,它可以通过实现System.IDisposable
接口确保清理),如GitHub 问题 #7930 中所述;GitHub PR #9900旨在解决引入专用cleanup
块的问题。聚合cmdlet - 那些必须在能够产生输出之前收集所有输入的cmdlet -永远不会产生输出;这是一个简单的例子:
PS> do { 5..1 | % { $_; if ($_ -eq 3) { break } } | Sort-Object } while ($false)
# !! NO OUTPUT, because Sort-Object's EndProcessing() method was never called.
Run Code Online (Sandbox Code Playgroud)
[1] 当您使用语句检查单个值时,如您所料switch
,break
退出该语句。如果正在处理值的数组(集合),则break
也立即退出该语句,而不处理数组中的其他元素;continue
相比之下,继续处理下一个元素。
[2] 另一种选择是用于throw
生成脚本终止错误,您可以通过将管道包含在try
/catch
语句中来捕获该错误,如此答案中所示。但是,这具有在自动$Error
集合中记录条目的副作用,即使在概念上没有发生实际错误。
您可以管道输出并使用 foreach 检查每一行,如果该行等于某个字符串,您可以使用它break
来停止命令:
Get-Content path\to\text\file\to\be\read.txt -wait | % {$_ ; if($_ -eq "yourkeyword") {break}}
Run Code Online (Sandbox Code Playgroud)
例如,如果您运行上面的命令并在另一个 shell 中执行以下操作:
"yourkeyword" | Out-File path\to\text\file\to\be\read.txt -Append
Run Code Online (Sandbox Code Playgroud)
显示Get-Content
新行并停止。
解释:
| %
- foreach 函数运行时文件中的行或添加到文件中的行
$_;
- 首先写出 foreach 的行,然后执行另一个命令
if($_ -eq "yourkeyword") {break}
- 如果 foreach 的行等于您想要的关键字/行,则停止Get-Content
归档时间: |
|
查看次数: |
2155 次 |
最近记录: |