【问题标题】:How to Select-String multiline?如何选择字符串多行?
【发布时间】:2019-03-27 09:18:35
【问题描述】:

我正在尝试在多行文本上Select-String

例子:

 "This is line1
 <Test>Testing Line 2</Test>
 <Test>Testing Line 3</Test>"

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

Select-String -Pattern "Line1"

【问题讨论】:

    标签: powershell select-string


    【解决方案1】:

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

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

    Get-Content -Raw file.txt | Select-String -Pattern Line1
    

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


    相比之下,如果您想保留每行匹配,但也捕获固定数量的环绕行,请使用-Context 参数。

    Get-Content file.txt | Select-String -Pattern Line1 -Context 0, 2
    

    Ansgar Wiechers' helpful answer 展示了如何从结果中提取所有行。

    【讨论】:

    • Select-String operates on its input objects individually 这是关键点!
    • 在提示符与脚本中也会发生奇怪的事情。在提示符下,select-string 在windows的原始字符串行尾查找\r,提示符处存在粘贴制表符或插入文字制表符的问题。
    【解决方案2】:

    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
    }
    

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

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

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

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

    Select-String -Pattern 'Line1' -Context 0,2 | ForEach-Object {
        $_.Line
        $_.Context.PostContext
    }
    

    【讨论】:

      猜你喜欢
      • 2016-07-12
      • 2021-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-25
      • 2023-03-09
      • 1970-01-01
      相关资源
      最近更新 更多