将与模式匹配的行从文件夹中的所有文本文件提取到单个输出文件

Jab*_*mal 7 powershell foreach filtering get-childitem select-string

我试图在文件夹中的所有文件中提取以"%%"开头的每一行,然后将这些行复制到单独的文本文件中.目前在PowerShell代码中使用此代码,但我没有得到任何结果.

$files = Get-ChildItem "folder" -Filter *.txt
foreach ($file in $files)
{
if ($_ -like "*%%*")
{
Set-Content "Output.txt" 
}  
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*ton 13

我认为mklement0的使用建议Select-String是要走的路.添加到他的回答,您可以通过管道输出Get-ChildItemSelect-String使整个过程变得PowerShell的一个衬垫.

像这样的东西:

Get-ChildItem "folder" -Filter *.txt | Select-String -Pattern '^%%' | Select -ExpandProperty line | Set-Content "Output.txt"
Run Code Online (Sandbox Code Playgroud)


mkl*_*nt0 7

Select-String小命令提供了一个更简单的解决(PSv3 +语法):

(Select-String -Path folder\*.txt -Pattern '^%%').Line | Set-Content Output.txt
Run Code Online (Sandbox Code Playgroud)
  • Select-String通过其-Path参数接受文件名/路径模式,因此,在这种简单的情况下,不需要Get-ChildItem.

    • 相反,如果输入文件选择是递归的或使用更复杂的标准,则可以将Get-ChildItem输出管道输出Select-String,如Dave Sexton的有用答案所示.
    • 请注意,根据文档,Select-String默认情况下假设输入文件是UTF-8编码的,但您可以使用-Encoding参数更改它; 还考虑下面讨论的输出编码.
  • Select-String-Pattern参数需要正则表达式而不是通配符表达式.
    ^%%仅匹配行%%start(^)处的文字.

  • Select-String输出包含每个匹配信息的[Microsoft.PowerShell.Commands.MatchInfo] 对象 ; 每个对象的.Line属性包含匹配的输入行的全文.

  • Set-Content Output.txt 将所有匹配的行发送到单个输出文件 Output.txt

    • Set-Content使用系统的遗留Windows代码页(8位单字节编码 - 即使文档错误地声称生成了ASCII文件).
      如果要显式控制输出编码,请使用-Encoding参数; 例如,... | Set-Content Output.txt -Encoding Utf8.
    • 相比之下,>输出重定向操作符始终创建UTF-16LE文件(编码PowerShell调用Unicode),Out-File 默认情况下(可以更改-Encoding).
      另请注意>/ Out-File将PowerShell的默认格式应用于输入对象以获取要写入输出文件的字符串表示形式,而Set-Content将输入视为字符串(.ToString()如果需要,则调用输入对象).在这种情况下,由于所有输入对象都已经是字符串,因此没有区别(可能除了字符编码).

至于你尝试过的:

  • $_在你的内部foreach ($file in $files)引用一个文件(一个[System.IO.FileInfo]对象),所以你有效地*%%*根据输入文件的名称而不是它的内容来评估你的通配符表达式.

  • 除此之外,通配符模式*%%*将匹配输入字符串中的%% 任何位置,而不仅仅是在其开头(您必须使用%%*).

  • Set-Content "Output.txt"呼叫丢失的输入,因为它不是一个管道的一部分,并且,在没有管道输入,无-Value参数传递.

    • 但是,即使您确实提供了输入,输出文件Output.txt也会在循环每次迭代作为整体重写.foreach