【问题标题】:grep - limit number of files readgrep - 限制读取的文件数
【发布时间】:2016-12-30 20:23:08
【问题描述】:

我有一个包含超过 100,000 个文件的目录。我想知道字符串"str1" 是否作为这些文件内容的一部分存在。

命令: grep -l 'str1' * 读取所有文件所需的时间太长。

如果找到匹配项,我如何要求grep 停止读取任何进一步的文件?有单行吗?

注意:我已经尝试过grep -l 'str1' * | head,但该命令所花费的时间与上一个命令一样多。

【问题讨论】:

  • 命令在文件少的目录下有效吗?
  • 也许,已经在这里回答了:stackoverflow.com/questions/14093452/…
  • head -1 可以解决问题
  • 如果你有很多文件,也许是 glob 非常慢。 find path/to/directory/ -type f -exec grep -l 'str1' /dev/null {} + 怎么样?
  • 在搜索固定字符串时,请注意使用fgrep 代替grep

标签: linux bash grep


【解决方案1】:

在命令 args 中命名 100,000 个文件名会导致问题。它可能超过了 shell 命令行的大小。

但是,如果您使用递归选项,只需使用文件所在目录的名称(如果您想在当前目录中搜索文件,则为 .),则不必命名所有文件:

grep -l -r 'str1' . | head -1

【讨论】:

  • 为了更精彩,我会加入LC_ALL="C" grep -m1 -l -r 'str1' . | head -1
  • @gniourf_gniourf,OP 的问题被标记为 linux,所以我认为可以安全地假设他们正在使用 GNU grep。
  • 还不错...;)
  • @user2070775:这就是为什么 Bill 说要使用 grep -r 而不是 glob(这也是我建议在评论中使用 find 的原因)。
  • @bishop,我没有包含-m 1,因为它是多余的,因为-l 在找到第一个匹配项后停止读取文件。
【解决方案2】:

使用grep -m 1 以便 grep 在文件中找到第一个匹配项后停止。它对于大型文本文件非常有效。

grep -m 1 str1 * /dev/null | head -1

如果只有一个文件,那么上面的 /dev/null 确保 grep 确实在输出中打印出文件名。

如果您想在任何文件中找到第一个匹配项后停止:

for file in *; do
  if grep -q -m 1 str1 "$file"; then
    echo "$file"
    break
  fi
done

当您的目录包含大量文件时,for 循环还可以帮助您避免 too many arguments 问题。

【讨论】:

  • 非常好。我希望找到一个班轮,但这些陈述会做。
  • 请注意,OP 已经在使用-l,这使得grep 在第一次匹配后停止。
  • for file in * 永远不会遭受“太多参数”的困扰,这是一种解决方法。例如,请参见:in-ulm.de/~mascheck/various/argmax
  • for file in * 在 shell 中进行特殊处理是一件新事物(嗯,在某些时候)。我知道过去(1990 年代)的各种 shell 在扩展 shell 内置项时存在许多错误和溢出问题。我不会依赖它,除非您知道您将使用的唯一 shell 以这种方式工作。
  • @gniourf_gniourf 很公平——但是至少在我的系统上,带有进程替换和findwhile 方法甚至更慢。我只是指出,我认为没有必要在 for 循环中解决“参数列表太长”(@ZanLynx 的评论告诉我这并不总是正确的)。
猜你喜欢
  • 2018-01-31
  • 2011-01-11
  • 1970-01-01
  • 2013-05-14
  • 1970-01-01
  • 2011-10-25
  • 1970-01-01
  • 2022-12-20
  • 2018-09-21
相关资源
最近更新 更多