8

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

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

4 回答 4

17

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

像这样的东西:

Get-ChildItem "folder" -Filter *.txt | Select-String -Pattern '^%%' | Select -ExpandProperty line | Set-Content "Output.txt"
于 2016-12-09T07:52:10.727 回答
9

cmdlet 提供了一个更简单的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传递任何参数。

    • 但是,即使您确实提供了输入,输出文件Output.txt也会在循环的每次迭代作为一个整体被重写foreach
于 2016-12-09T04:23:23.197 回答
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/

于 2016-12-09T04:07:20.170 回答
1

首先你必须使用

获取内容

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

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

于 2016-12-09T04:09:55.597 回答