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

Posted

技术标签:

【中文标题】从文件夹中的所有文本文件中提取与模式匹配的行到单个输出文件【英文标题】:Extract lines matching a pattern from all text files in a folder to a single output file 【发布时间】:2017-04-24 11:37:26 【问题描述】:

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

$files = Get-ChildItem "folder" -Filter *.txt
foreach ($file in $files)

if ($_ -like "*%%*")

Set-Content "Output.txt" 
  

【问题讨论】:

使用了这段代码,我在这里做错了 $files = Get-ChildItem "FOLDER" -Filter *.txt foreach ($file in $files) (Select-String -Path *. txt -Pattern '^%%').Line |设置内容“Output.txt” 【参考方案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/

【讨论】:

【参考方案2】:

首先你必须使用

获取内容

为了得到文件的内容。然后您进行字符串匹配,并在此基础上再次将内容设置回文件。使用 get-content 并在 foreach 中放置另一个循环来迭代文件中的所有行。

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

【讨论】:

【参考方案3】:

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 docs、Select-String 默认假定输入文件是 UTF-8 编码的,但您可以使用 -Encoding 参数更改它;还要考虑下面讨论的输出编码。

Select-String-Pattern 参数需要正则表达式,而不是通配符表达式。^%% 仅匹配开头的文字%% (^) 一行。

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

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

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

至于你尝试了什么

$_ 在您的foreach ($file in $files) 中指的是一个文件(一个[System.IO.FileInfo] 对象),因此您可以根据输入文件的name 而不是它的内容

除此之外,通配符模式 *%%* 将匹配输入字符串中的 %% anywhere,而不仅仅是在其 start 处(你会改为使用%%*)。

Set-Content "Output.txt" 调用缺少 输入,因为它不是管道的一部分,并且在没有管道输入的情况下,没有传递 -Value 参数。

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

【讨论】:

【参考方案4】:

我认为 mklement0 建议使用Select-String 是可行的方法。添加到他的答案中,您可以将Get-ChildItem 的输出通过管道传输到Select-String 中,这样整个过程就变成了Powershell one liner。

类似这样的:

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

【讨论】:

以上是关于从文件夹中的所有文本文件中提取与模式匹配的行到单个输出文件的主要内容,如果未能解决你的问题,请参考以下文章

在 Unix 提示符下,如何从与模式匹配的文件中提取可变数量的行(可能包括空行)?

打印文件中从匹配行到文件末尾的行数

csv 文件中的模式匹配并附加到匹配的行

文本三剑客之awk

在文本字符串中搜索模式,然后提取匹配的模式

如何获取从最后一个匹配到文件末尾的行?