如何选择字符串多行?

van*_*191 6 powershell select-string

我正在尝试Select-String使用多行文本。

例子:

 "This is line1
 <Test>Testing Line 2</Test>
 <Test>Testing Line 3</Test>"
Run Code Online (Sandbox Code Playgroud)

我希望能够在Select-String. 但是,它仅在我执行时选择第一行Select-String -Pattern "Line1"。如何将所有 3 行提取在一起?

Select-String -Pattern "Line1"
Run Code Online (Sandbox Code Playgroud)

Ans*_*ers 8

Select-String允许通过参数选择匹配行之前或之后的给定行数-Context-Context 2,0选择前面 2 行,-Context 0,2选择后面 2 行,-Context 2,2选择匹配之前的 2 行以及匹配之后的 2 行。

不过,您不会将匹配行和上下文行集中在一起,因此如果您希望将匹配行和上下文作为单个字符串,则需要将它们组合起来:

Select-String -Pattern 'Line1' -Context 0,2 | ForEach-Object {
    $($_.Line; $_.Context.PostContext) | Out-String
}
Run Code Online (Sandbox Code Playgroud)

正如 @mklement0 在评论中正确指出的那样,上面的速度相对较慢,如果您只处理几个匹配项,这不是问题,但如果您需要处理数百或数千个匹配项,这就会成为问题。为了提高性能,您可以将值合并到单个数组中并使用-join运算符:

Select-String -Pattern 'Line1' -Context 0,2 | ForEach-Object {
    (,$_.Line + $_.Context.PostContext) -join [Environment]::NewLine
}
Run Code Online (Sandbox Code Playgroud)

请注意,这两个代码片段不会产生完全相同的结果,因为Out-String将换行符附加到每一行(包括最后一行),而仅在行之间-join放置换行符(而不是在最后一行的末尾)。不过,每个片段都可以修改以产生与另一个片段相同的结果。修剪第一个示例中的字符串以删除尾随换行符,或将另一个换行符附加到第二个示例中的字符串中。

如果您希望输出为单独的行,只需输出LinePostContext属性,而不将它们合并到一个字符串中:

Select-String -Pattern 'Line1' -Context 0,2 | ForEach-Object {
    $_.Line
    $_.Context.PostContext
}
Run Code Online (Sandbox Code Playgroud)


mkl*_*nt0 7

Select-String单独对其输入对象进行操作,如果您将文件路径直接传递给它(通过-Path-LiteralPath),或者从 管道输出Get-Content,则在每一上执行匹配。

因此,将您的输入作为单个多行 string 传递,如果它来自文件,则最容易通过Get-Content -Raw(PSv3+) 实现:

Get-Content -Raw file.txt | Select-String -Pattern Line1
Run Code Online (Sandbox Code Playgroud)

请注意,这意味着如果模式匹配,则文件的整个内容都是 output,可通过 output 对象的.Line属性访问。


相比之下,如果您想保留每行匹配但同时捕获固定数量的周围行,请使用该-Context参数。

Get-Content file.txt | Select-String -Pattern Line1 -Context 0, 2
Run Code Online (Sandbox Code Playgroud)

Ansgar Wiechers 的有用答案显示了如何从结果中提取所有行。

  • `Select-String 单独对其输入对象进行操作`这是关键点! (2认同)