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

时间:2016-12-09 03:56:08

标签: powershell foreach filtering get-childitem select-string

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

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

4 个答案:

答案 0 :(得分:12)

我认为mklement0建议使用Select-String是要走的路。添加到他的答案中,您可以将Get-ChildItem的输出传递到Select-String,以便整个过程成为Powershell单行。

这样的事情:

Get-ChildItem "folder" -Filter *.txt | Select-String -Pattern '^%%' | Select -ExpandProperty line | Set-Content "Output.txt"

答案 1 :(得分:7)

Select-String cmdlet提供了一个更简单的解决方案(PSv3 +语法):

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

    • 相反,如果输入文件选择是递归的或使用更复杂的条件,则可以将Get-ChildItem的输出传送到Select-String,如Dave Sexton's helpful answer中所示。
    • 请注意,according to the docsSelect-String默认情况下假设输入文件是UTF-8编码的,但您可以使用-Encoding参数进行更改;还要考虑下面讨论的输出编码。
  • Select-String的{​​{1}}参数需要正则表达式而不是通配符表达式。
    -Pattern仅匹配一行 start ^%%)的文字%%

  • ^输出Select-String 个对象,其中包含有关每个匹配的信息;每个对象的[Microsoft.PowerShell.Commands.MatchInfo]属性包含匹配的输入行的全文。

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

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

至于您尝试过的内容

    您在.ToString()内的
  • $_引用文件foreach ($file in $files)对象),因此您正在有效地评估通配符表达式{{ 1}}针对输入文件的名称而不是内容

  • 除此之外,通配符模式[System.IO.FileInfo]将匹配输入字符串中的*%%* ,而不仅仅是 start (你必须使用*%%*代替。

  • %%调用缺少输入,因为它不是管道的一部分,并且在没有管道输入的情况下,没有传递%%*个参数

    • 但是,即使您确实提供了输入,输出文件Set-Content "Output.txt"也会在-Value循环的每次迭代重写

答案 2 :(得分:1)

ls *.txt | %{
$f = $_
  gc $f.fullname | {
     if($_.StartWith("%%") -eq 1){
        $_ >> Output.txt
     }#end if
  }#end gc
}#end ls

别名

ls - Get-ChildItem
gc - Get-Content
% - ForEach
$_ - Iterator variable for loop
>> - Redirection construct
# - Comment

http://ss64.com/ps/

答案 3 :(得分:0)

首先你必须使用

  

获取内容

以获取文件的内容。然后你进行字符串匹配,并根据你再次将内容设置回文件。使用 get-content 并在 foreach 中添加另一个循环来迭代文件中的所有行。

我希望这个逻辑可以帮助你