在Powershell的Select-String命令中使用上下文

4
我有一份脚本,它可以在一个目录中的文件内容中搜索一系列字符串(这些字符串存储在一个txt文件中)。我想修改它,以便还可以列出找到的字符串周围的文本(这些是普通字符串,不是正则表达式)。我尝试了很多次,似乎需要使用-Context参数,但我不确定如何从中获取文本。
另外,我要搜索的文件可能没有换行符,所以如果能够只获取搜索项之前和之后的xx个字符,那就更好了。
以下是我目前的脚本(省略了循环文件部分):
$result = Get-Content $file.FullName | Select-String $control -quiet  
If ($result -eq $True) 
{ 
  $match = $file.FullName 
  "Match on string :  $control  in file :  $match" | Out-File $output -Append 
  Write-host "Match on string :  $control  in file :  $match"
} 

如果能写出内容,那就太好了。看起来我需要使用 $_Matches,但不确定如何使用。
2个回答

1
如果$control只是一个普通的字符串,你能把它转换成正则表达式吗?
$n  = 3
$re = "(.{0,$n})(" + [Regex]::Escape($control) + ")(.{0,$n})"

$result = (Get-Content $file.FullName) -match $re

有了这个,$matches 哈希表应该让你可以访问匹配前后的 $n 个字符:

if ($result.Length -gt 0) {
  echo "Before: $($matches[1])"
  echo "After:  $($matches[3])"
}

你也可以修改检查条件为 if ($result),这样看起来更好(在我看来)。但也许我在 PowerShell 中太过追求简洁了 ;) - Joey
这会让$result看起来像一个布尔值,但它实际上不是。即使编程语言允许,我还是更喜欢避免这种混淆。 - Ansgar Wiechers
好的,很公平。在 PowerShell < 3 中,如果文件仅包含单个匹配行,则可能会出现错误 :-)。 (当然,如果只使用 $result 并且它是空字符串时,即使只有一个匹配行,您也会遇到问题,但这在该场景中不太可能发生。) - Joey
我经常遇到“无法检索变量'$matches',因为它尚未设置”的错误。 - user1612851
我认为如果前后的字符是换行符,它就无法找到匹配项。我认为使用 [\s\S] 可以解决这个问题。 - user1612851

0

这是我现在拥有的,看起来它能够工作:

  $regex = "[\s\S]{0,$ContextChars}$SearchTerm[\s\S]{0,$ContextChars}"
  $results = Get-Content $file.FullName | Select-String -Pattern $regex -AllMatches | % { $_.Matches } | % { $_.Value }      

  if ($results)
  {
    foreach($result in $results)
    {
      $display = $result
      "File: $file   Match ---$display---"  
    }
  }  

我唯一希望拥有但不知道如何获得的是匹配行的行号。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接