如何访问 Powershell Select-String Return 值

How to Access Powershell Select-String Return Values

我在文本文件的开头有一个 header 部分 test.txt:

BLOGS-BODGER
SMALLTOWN COMPOSITE ROLL
PAGE 6
PAGE 7
SMALLTOWN COMPOSITE ROLL
BOOMER-BYGRAVE

我正在通过以下方式从此 header 中提取数据:

$filesPathText = "C:\test\test3\test.txt"

# find NAME-NAME strings in text file test.txt
$names = Select-String -Path $filesPathText -Pattern '[A-Z]-[A-Z]'
Write-Host "First name" $names[0] "Second name" $names[1]

# find PAGE X strings in text file test.txt
$pages = Select-String -Path $filesPathText -Pattern 'PAGE'
Write-Host "First page" $pages[0] "Second page" $pages[1]

输出如下:

First name C:\test\test3\test.txt:3:BLOGS-BODGER Second name C:\test\test3\test.txt:8:BOOMER-BYGRAVE
First page C:\test\test3\test.txt:5:PAGE 6 Second page C:\test\test3\test.txt:6:PAGE 7

我可以通过以下方式访问行号:

[int]$lineNum = $names[1].LineNumber

那么我该如何为 NAME & PAGE 值做类似的事情。也就是去掉路径&行号数据,把NAME&PAGE数据赋给一个变量?

此文档已关闭 Example 3: Find a pattern match but doesn't go into parsing out individual elements. This SO post 引用了管道输出到 Select-Object 和扩展属性??

任何 suggestions/explanations 将不胜感激。

Santiago Squarzon在评论中提供了关键指针:

  • 要从每个匹配项的 [Microsoft.PowerShell.Commands.MatchInfo] instance that Select-String 输出中获取 行文本 ,请访问其 .Line 属性.

    • 注意:如果您 只是 寻找行文本,PowerShell (Core) 7+ 提供了一个更简单的解决方案,即 -Raw开关.

    • 属性名称可能会产生误导,因为严格来说,它是匹配输入字符串的整个文本,其中,根据提供输入的方式,它本身可能由 多行 行组成。[1]

  • 要获得匹配的搜索模式 - 只有在传递了多个模式时才有意义 - 使用.Pattern 属性.

  • 要仅获取一行的匹配部分,即与搜索模式匹配的部分,请使用.Matches.Value (或者,更严格地说,.Matches[0].Value)。

    • 注意:.Matches 数组 [System.Text.RegularExpressions.Match] 个实例,但该数组只包含 多个 元素,如果还指定了 -AllMatches,为了请求潜在的 多个 匹配 每行 (每个输入对象) .

    • 如果您的搜索正则表达式包含 捕获组 (包含在 (...) 中的子表达式),您可以通过 .Matches[0].Groups 属性.[2]

为了说明这三者;请注意,正则表达式 pag. 用于 (case-insensitively) 逐字匹配字符串 PAGE,以说明 .Pattern.Matches.Value 之间的区别;此外,这些值包含在 [...] 中以进行描述:

'PAGE 6' | Select-String -Pattern pag. | ForEach-Object {
  [pscustomobject] @{
    Line = '[{0}]' -f $_.Line
    Pattern = '[{0}]' -f $_.Pattern    
    MatchingLinePart = '[{0}]' -f $_.Matches.Value
  }
}

输出:

Line     Pattern MatchingLinePart
----     ------- ----------------
[PAGE 6] [pag.]  [PAGE]

[1] 例如("a`nb" | Select-String a).Line 输出完整的 two-line 输入字符串,因为它是作为单个输入对象提供的。

[2] 例如,'PAGE 6' | Select-String 'page (\d+)' | ForEach-Object { $_.Matches[0].Groups[1].Value } 输出字符串 6;索引 1 指的是正则表达式中的第一个(也是唯一一个)捕获组 ((...))。


发现 cmdlet 的输出数据类型:

  • 通过Get-Member:

    • 通过管道将具体调用传递给 Get-Member 以发现该调用的输出类型及其成员;添加-Type Properties限制成员显示;例如:

      PS> 'foo' | Select-String foo | Get-Member -Type Properties 
      
          TypeName: Microsoft.PowerShell.Commands.MatchInfo
      
       Name       MemberType Definition
       ----       ---------- ----------
       Context    Property   Microsoft.PowerShell.Commands.MatchInfoContext Context {get;set;}
       Filename   Property   string Filename {get;}
       IgnoreCase Property   bool IgnoreCase {get;set;}
       Line       Property   string Line {get;set;}
       LineNumber Property   int LineNumber {get;set;}
       Matches    Property   System.Text.RegularExpressions.Match[] Matches {get;set;}
       Path       Property   string Path {get;set;}
       Pattern    Property   string Pattern {get;set;}
      
  • 通过 cmdlet 的文档:cmdlet 的帮助包含一个 OUTPUTS section,它描述了由该 cmdlet。

    • 要在本地查看此部分,您必须使用 -Full 开关调用 Get-Help,例如Get-Help Select-String -Full

      • -Full 导致冗长的输出,其中 OUTPUTS 部分可能被掩埋;要隔离它,请使用如下内容:

        (Get-Help Select-String -Full | Out-String) -replace '(?sm).+^(OUTPUTS.+?)^\S.+$', ''
        
    • 请注意,给定的 cmdlet 可能会根据情况产生 不同的 输出类型;例如,使用 -Quiet 开关 Select-String 发出布尔值。