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

9

我正在尝试从文件夹中的所有文件中提取以“%%”开头的每一行,然后将这些行复制到单独的文本文件中。目前在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 | Set-Content "Output.txt" } - Jabir Jamal
4个回答

19
我认为mklement0的建议使用Select-String是正确的。补充他的回答,您可以将Get-ChildItem的输出导入到Select-String中,使整个过程成为PowerShell单行代码。 类似这样的内容:
Get-ChildItem "folder" -Filter *.txt | Select-String -Pattern '^%%' | Select -ExpandProperty line | Set-Content "Output.txt"

9
Select-String 命令提供了一种更简单的解决方案(适用于 PSv3+ 语法):
(Select-String -Path folder\*.txt -Pattern '^%%').Line | Set-Content Output.txt

  • Select-String通过其-Path参数接受文件名/路径模式,因此在这种简单情况下,不需要使用Get-ChildItem

    • 相反,如果您的文件选择是递归的或使用更复杂的条件,则可以将Get-ChildItem的输出导入到Select-String中,如Dave Sexton的有用答案所示。
    • 请注意,根据文档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位单字节编码 - 即使文档错误地声称生成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参数。

    • 即使您提供了输入,foreach循环的每次迭代都会将输出文件Output.txt整体覆盖的方式进行重写

1

首先,您需要使用

Get-Content

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

希望这个逻辑能帮到您


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/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接