如何查找包含几个特定字符串但不一定在同一行的所有文件?

4
在Linux中,grep -r <string> <path>是查找<path>下所有包含<string>的文件的常用方法。但如果我想要查找包含几个字符串的所有文件呢?使用grep -r <string1> <path> | grep <string2>可以得到包含<string1><string2>的所有文件在同一行中,但如何获取包含<string1><string2>的文件分别显示在不同行中?

https://dev59.com/-WQn5IYBdhLWcg3wRlYM#20950539 - Dilawar
1个回答

5

你可以尝试

grep -rl searchstring1 . | xargs grep -l searchstring2

要获取包含两个搜索字符串 searchstring (不一定在同一行)的目录 . 中的文件名列表。如果您需要更多的搜索字符串,可以级联使用:

grep -rl searchstring1 . \
  | xargs grep -l searchstring2 \
  | xargs grep -l searchstring3

如果文件名含有空格等特殊字符,则使用xargs时会出现问题,这是需要注意的。为了避免这种特殊情况(或确保不会出现该问题),可以使用0字节终止的字符串:

grep -rlZ searchstring1 . \
  | xargs -0 grep -lZ searchstring2 \
  | xargs -0 grep -l searchstring3

你可以使用以下方法来检查输出:

grep -rlZ searchstring1 . \
  | xargs -0 grep -lZ searchstring2 \
  | xargs -0 grep -lZ searchstring3 \
  | xargs -0 egrep 'searchstring2|searchstring2|searchstring3' /dev/null \
  | less

完全不同的方法是直接使用find(但这将启动大量的grep进程,因此可能不太高效):

find . -type f \( \
  -exec grep -q searchstring1 {} \; -a \
  -exec grep -q searchstring2 {} \; -a \
  -exec grep -q searchstring2 {} \; \) -print

xargs是一个不错的选择,这肯定会起作用,我会接受你的答案,但是有没有其他选择呢?我的意思是,查找具有少量字符串的文件是一个非常基本的问题,我希望它可以在没有管道的情况下解决。这是一个可扩展性问题,理想情况下,我正在寻找类似于“<我正在寻找的命令和标志> <字符串列表> <路径>”的语法。为简单起见,我们可以假设所有字符串都是普通的字母数字字符。 - e271p314
我添加了一个“find”版本,以防您更喜欢它。我能想到的其他选项涉及使用Python或类似工具。我无法想到第三种仅使用Unix标准工具的方法。 - Alfe
总的来说,我认为你的答案已经足够了,不过,如果有不包括管道的答案,我会很高兴听到。 - e271p314
我只是好奇:你反对管道的根据是什么? - Alfe
正如我所说,首先是可扩展性,其次是在我看来,只有一个命令或标志可以处理这种特定情况才有意义。即使您的第一种方法几乎与无管道解决方案一样可扩展,但为了可读性和易用性,我更喜欢单个指定的命令。 - e271p314
1
请注意,如今在多核处理器上将任务分成几个独立的进程通常会带来优势。但我理解你的观点。 - Alfe

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