Powershell 使用 Select-String 搜索行终止

Powershell searching for line termination using Select-String

我正在使用 PS v5.1

通常,如果我想搜索包含字符串的文件,我会使用这种模式:

Get-ChildItem -recurse | Select-String "searchstring"

如果我要搜索的是行终止字符 (\r\n),这似乎不起作用。 Select-String 文档状态:

Select-String is based on lines of text. By default, Select-String finds the first match in each line and, for each match, it displays the file name, line number, and all text in the line containing the match.

看来 sls 'helpfully' 删除了我的行终止字符。 我可以这样做:

gci *|get-content -raw|sls "\r\r\n" -list

但这真的完全不一样,因为它丢失了文件名。我知道我可以写一个更长的 foreach 结构,例如:

foreach ($f in (gci -recurse *)) {
    if ($f.PSIsContainer) {
        continue
        }
    $c = Get-Content -raw $f.FullName
    if ($c.Length -ne 0) {
        $i = $c.IndexOf("`r`r`n")
        if ($i -gt 0) {
            Write-Output $f.FullName
            }
        }
    }

但这对于我想做的事情来说似乎相当冗长和复杂。

是否有更好的(如简洁的单行)方法来进行此类搜索?

确实,Select-String 设计为在将文件信息对象作为输入时对单独的行进行操作,因此您无法以这种方式检查换行符。

Get-Content -Raw 允许您读取整个文件,作为单个字符串,PowerShell 的文件系统提供程序还向该字符串添加 NoteProperty 成员,特别是 .PSPath 属性 反映了输入文件路径。

而不是 Select-String,然后您可以在每个文件内容字符串上使用 -match 运算符来查找感兴趣的序列,并回显 .PSPath 属性 匹配时的值:

Get-ChildItem -File -Recurse | Get-Content -Raw | ForEach-Object {
  if ($_ -match '\r\r\n') { Convert-Path $_.PSPath }
}

请注意,Convert-Path 需要将 .PSPath 中报告的 PowerShell 提供程序限定路径(例如,Microsoft.PowerShell.Core\FileSystem::C:\Users\jdoe\file.txt)转换为本机文件系统路径(例如,C:\Users\jdoe\file.txt).
(这只是必要的,因为输入文件信息对象是通过管道提供的。)