Unix命令列出包含字符串但* NOT *包含另一个字符串的文件

时间:2011-02-14 06:44:21

标签: linux command-line find command grep

如何递归查看具有一个字符串且特别是没有其他字符串的文件列表?另外,我的意思是评估文件的文本,而不是文件名。


结论:

根据评论,我最终使用了:

find . -name "*.html" -exec grep -lR 'base\-maps' {} \; | xargs grep -L 'base\-maps\-bot'

此返回的文件带有“base-maps”而不是“base-maps-bot”。谢谢!!

6 个答案:

答案 0 :(得分:42)

试试这个:

grep -rl <string-to-match> | xargs grep -L <string-not-to-match>

说明:grep -lr使grep递归(r)输出包含<string-to-match>的所有文件的列表(l)。 xargs循环遍历这些文件,在每个文件上调用grep -Lgrep -L只会在文件不包含<string-not-to-match>时输出文件名。

答案 1 :(得分:3)

不需要在上面的答案中使用xargs;你可以做到这样的事情:

find . -type f -exec grep -q <string-to-match> {} \; -not -exec grep -q <string-not-to-match> {} \; -print

grep -q表示安静地运行但返回退出代码,表示是否找到匹配项;然后find可以使用该退出代码来确定是否继续执行其余选项。如果-exec grep -q <string-to-match> {} \;返回0,则它将继续执行-not -exec grep -q <string-not-to-match>{} \;。如果它也返回0,它将继续执行-print,这将打印文件的名称。

正如另一个答案所指出的那样,以这种方式使用findgrep -Rl具有主要优势,您只想搜索某种类型的文件。另一方面,如果您确实想要搜索所有文件,grep -Rl可能更快,因为它使用一个grep进程为所有文件执行第一个过滤器,而不是单独的{{1}每个文件的进程。

答案 2 :(得分:1)

这些答案似乎与匹配 BOTH 字符串相关。以下命令应该更好:

grep -l <string-to-match> * | xargs grep -c <string-not-to-match> | grep '\:0'

答案 3 :(得分:1)

这是一个更通用的结构:

find . -name <nameFilter> -print0 | xargs -0 grep -Z -l <patternYes> | xargs -0 grep -L <patternNo>

此命令输出名称与<nameFilter>匹配的文件(根据需要调整find谓词),其中包含<patternYes>但不包含<patternNo>

增强功能包括:

  • 适用于包含空格的文件名。
  • 它允许您按名称过滤文件。

如果您不需要按名称进行过滤(通常需要考虑当前目录中的所有文件),您可以删除find并将-R添加到第一个grep

grep -R -Z -l <patternYes> | xargs -0 grep -L <patternNo>

答案 4 :(得分:0)

查找。 -maxdepth 1-名称“ * .py” -exec grep -L“字符串不匹配” {} \;

此命令将在同一目录中获取所有不包含“字符串不匹配”的“ .py”文件。

答案 5 :(得分:0)

要匹配字符串A并排除在我使用的同一行中出现的字符串B和C,并加上引号以允许搜索字符串包含空格

grep -r <string A> | grep -v -e <string B> -e "<string C>" | awk -F ':' '{print $1}'

说明:grep -r递归过滤输出格式匹配的所有行

文件名:第

要从这些行中排除(grep -v)那些还包含-e字符串B或-e字符串C的行。awk用于仅将第一个字段(文件名)使用冒号作为字段分隔符-F < / p>