【问题标题】:Select files from sub-directories and print a certain line from each file [duplicate]从子目录中选择文件并从每个文件中打印某一行[重复]
【发布时间】:2017-05-23 12:58:56
【问题描述】:

我有一个包含几个子目录的目录,这些子目录有很多文件,我对*.txt 文件感兴趣。我想去每个子目录,阅读*.txt 文件并打印与“pattern”匹配的特定行。 我宁愿把它当作单线。

这是我尝试的命令。

for i in $(ls -d *_fastqc); do cd $i; awk '/FAIL/ {print $0}' ls -l su*.txt; done

我收到一个错误命令,如:

awk:命令。 line:1: 致命:无法打开文件 `-rw-rw-r--' 进行读取(没有这样的文件或目录)

这里可能出了什么问题?

【问题讨论】:

  • 错误来自您的ls -l 显示长格式作为 awk 的输入。尝试ls -1,但之前评论中的链接是正确的方法,而不是循环。

标签: bash awk


【解决方案1】:

Awk 不是用于此目的的正确工具,请参阅 why you shouldn't be parsing ls ouput

而是使用GNU find 列出与您的条件匹配的文件,xargs 用于对从findgrep 返回的输出进行限制以进行模式匹配。

find . -type f -name "*.txt" -print0 | xargs -0 grep "FAIL"

-print0 (a GNU find specific option) 在每个文件/目录的末尾附加一个NULL 字符以处理带有空格/特殊字符的文件,xargs -0 将来自stdin 的输入拆分为\0 作为分隔符。在返回的文件上使用grep,如果匹配则返回文件中的行。

【讨论】:

  • 这里不需要 xargs...find -type f -name '*.txt' -exec grep -F 'FAIL' {} +
  • 也可以使用 GNU grep,不需要 find...grep --include='*.txt' -rF 'FAIL'
  • @Sundeep GNU 的家伙们通过提供 grep 选项来查找文件真的搞砸了。有一个非常好的工具,名称非常明显。接下来他们将给 grep 什么 - 对其输出进行排序的选项或 stat 文件的选项? find 文件的工具名为find - 只需使用它。
  • @EdMorton 不同意,find 是查找文件,grep 是在文件或流中查找元素(文本)。在这种情况下,您在首先使用 find 时分叉了 grep。所以它将取决于其他标准来定义哪种方式是最好的(性能、内存、代码阅读、兼容性......)
  • @NeronLeVelu 我了解可能的性能影响,但 find(在 Sundeeps 的第一条评论中)将一次调用 grep 多个文件,而不仅仅是 1 个,这会最大限度地减少 grep -r 的任何潜在性能优势。事实上 grep -r 正在做 find 已经做的事情,这违反了 UNIX 原则,即每个工具都做好一件事,并使潜在的 arg 列表成为噩梦。通过提供 grep 参数来查找文件,他们使其与读取文件的所有其他工具不一致,例如sed、awk、cat、sort、uniq、head、tail 等。你也可以争论所有这些的性能改进
猜你喜欢
  • 1970-01-01
  • 2022-05-06
  • 2017-08-29
  • 1970-01-01
  • 2013-01-12
  • 1970-01-01
  • 2015-03-06
  • 2016-03-17
  • 1970-01-01
相关资源
最近更新 更多