-1

我有这个很好用的脚本,但我还需要它来返回行号和行。

如果我做

Select-String w:\test\york\*.* -pattern "mistake"

我明白了

W:\test\york\test.html:179:<p>如果您发现信息单上有错误,请联系该单据的雇主、付款人或管理员。</p>
W:\test\york\test.html:180:<p>如果您发现税务相关信息有误或对其他税务相关信息有特定账户问题,请致电个人所得税和信托查询热线拨打 1-800-959-8281。</p>

这是完美的。但是,在我的脚本中,是这样的:

param(
    [string]$pattern,
    [string]$path  
) 
$exclude = '*\test\*'
Get-ChildItem -Path $path -Recurse -Filter *.html | Where-Object {
    ForEach-Object {
        if (Get-Content $_.FullName | Select-String -Pattern "<h2>Stay Connected") {
            Select-String -InputObject (Get-Content $_.FullName | Out-String) -Pattern "(?sm)<main([\w\W]*)$pattern([\w\W]*)<h2>Stay Connected"
        } elseif (Get-Content $_.FullName | Select-String -Pattern "<h2>Soyez branch") {
            Select-String -InputObject (Get-Content $_.FullName | Out-String) -Pattern "(?sm)<main([\w\W]*)$pattern([\w\W]*)<h2>Soyez branch"
        } else {
            Select-String -InputObject (Get-Content $_.FullName | Out-String) -Pattern "(?sm)<main([\w\W]*)$pattern([\w\W]*)<\/main>"
        }
    }
} | Select Fullname | ? {$_.FullName -notlike $exclude}

我只在我的 CSV 中得到这个结果:

#TYPE Selected.System.IO.FileInfo
全名
W:\test\york\test.html

如何使用脚本在我的 CSV 文件中获取简单搜索的结果?


根据 Ansgar Wiechers 的回答进行编辑。

$pattern是“教科书”。

这是我当前的代码:

param(
    [string]$pattern,
    [string]$path,
    [string]$name  
) 
$expr = "(?sm)<main([\w\W]*)$pattern([\w\W]*)" +
        '(?:<h2>Stay Connected|<h2>Soyez branch|<\/main>)'
Get-ChildItem -Path $path -Recurse -Filter *.html |
    Select-String -Pattern $expr |
    Select-Object Path, LineNumber, Line |
    Export-Csv "W:\test\search_results\$name.csv" -NoType

如果我更换

$expr = "(?sm)<main([\w\W]*)$pattern([\w\W]*)" +
        '(?:<h2>Stay Connected|<h2>Soyez branch|<\/main>)'

经过

$expr = $pattern

我得到 6 个结果(这是正确的),但是如果我使用 Ansgar 提供的表达式,我没有得到任何结果。为了让表达式正常工作,我缺少什么?

4

1 回答 1

3

不要让事情变得比他们需要的更复杂。

$expr = "(?sm)<main([\w\W]*)$pattern([\w\W]*)" +
        '(?:<h2>Stay Connected|<h2>Soyez branch|<\/main>)'
$files = Get-ChildItem -Path $path -Recurse -Filter *.html
foreach ($filename in $files) {
    Get-Content $filename -Raw |
        Select-String -Pattern $expr } |
        Select-Object @{n='Path';e={$filename}}, LineNumber, Line |
        Export-Csv 'C:\path\to\your.csv' -NoType
}

无需检查每个文件两次。或者使用不同的表达方式。只需循环输出Get-ChildItem,将每个文件的内容通过管道传输到并选择结果对象Select-String的相关属性。MatchInfo

原则Select-String上甚至可以自己读取文件。但是,它将内容作为行数组处理,从而防止多行匹配。因此,您必须使用Get-Content -Raw(或Get-Content | Out-String在 PowerShell v2 及更早版本中)读取文件以获取一个字符串中的内容。

如果您需要过滤掉包含文件夹的路径,test您应该在Get-ChildItem

$files = Get-ChildItem -Path $path -Recurse -Filter *.html |
         Where-Object { $_.FullName -notlike $exclude }
foreach ($filename in $files) {
    Get-Content ...
}

从技术上讲,在之后也可以这样做Select-String

$files = Get-ChildItem -Path $path -Recurse -Filter *.html
foreach ($filename in $files) {
    ...
        Where-Object { $_.Path -notlike $exclude } |
        Export-Csv 'C:\path\to\your.csv' -NoType
}

但是,在处理后过滤输出是一种资源浪费,因为您可以过滤输入并避免首先生成您不想要的结果。

于 2016-03-07T20:52:53.490 回答