powershell 递归查找具有特定字符的行

f1tvaqid  于 2022-12-23  发布在  Shell
关注(0)|答案(1)|浏览(163)

我正在搜索所有行与'png'和'jpg'字符串在他们跨越多个文件夹的TXT文件。
尝试:

(Get-ChildItem K:\FILES -Recurse -Include '*.txt') | ForEach-Object {
    (Get-Content $_) -match '\.png','\.jpg' | out-file K:\Output.txt
   }

但是它没有输出任何东西。也没有错误。我最近做了类似的事情,它正在工作。我挠头想知道我在这里做错了什么...

mftmpeh8

mftmpeh81#

通过将Out-File调用 * 放在ForEach-Object脚本块 * 中,您将为每个输入文件 * 完全 * 重写输出文件,这样,* 最后一个 * 输入文件的结果--可能是 * none *-最终将成为文件的唯一内容。
立即修复是Out-File调用移动到它自己的管道段,以便它跨所有文件接收 * 所有 * 输出

Get-ChildItem K:\FILES -Recurse -Include '*.txt' | 
  ForEach-Object {
    @(Get-Content $_) -match '\.png', '\.jpg'
  } |
  Out-File K:\Output.txt

Note:从技术上讲,将-Append添加到ForEach-Object * 内部 * 的Out-File调用中也可以工作,但是应该 * 避免 * 这种方法:

  • 每个Out-File调用都必须打开和关闭输出文件,这使得操作要慢得多。
  • 您需要确保没有 * preexisting * 输出文件 * previous *-否则您将结束追加到该文件的现有内容。

但是,请考虑借助**Select-String*******加快命令的执行速度

Get-ChildItem K:\FILES -Recurse -Include '*.txt' | 
  Select-String -Pattern '\.png', '\.jpg' |
  ForEach-Object Line |
  Out-File K:\Output.txt

注:

  • PowerShell (Core) 7+中,您可以将-Raw开关与Select-String一起使用,它只直接输出所有匹配行的 * text *,在这种情况下不需要ForEach-Object Line

如果要在每个匹配行前加上源文件路径前缀

Get-ChildItem K:\FILES -Recurse -Include '*.txt' | 
  Select-String -Pattern '\.png', '\.jpg' |
  ForEach-Object { '{0}: {1}' -f $_.Path, $_.Line } |
  Out-File K:\Output.txt

Note:如果您将Select-String输出 * 直接 *(不使用-RawForEach-Object Line)通过管道传输到Out-File(或者如果您使用>),您将得到 * 相似 * 的输出(甚至包括 * 字符位置 *),但有 * 限制 *:

  • 您将在文件的顶部和底部得到一个空行。
  • 可能会 * 截断 * 较长的文本行。

原因是Out-File及其虚拟别名>将输入对象的 * for-display * 表示形式发送到输出文件,这并不意味着要进行 * 编程式 * 处理,而且可能会导致根据当前控制台窗口的行长度(列数)截断数据。

相关问题