如何查找包含一个条件但排除不同条件的文件

the*_*lar 11 grep find

我有一个源代码树,我希望找到包含某个单词且不得包含第二个单词的所有文件。这是因为我需要更新旧文件以包含一些新代码。

我知道我可以使用 find,但我觉得如果我尝试链接 grep 语句,它将不起作用,因为第二个 grep 语句将搜索第一个的结果,然后我迷路了。

我试过:

find . -type f -name "*.c" -exec grep -Hl "ABC" {} \; | grep -L "123"
Run Code Online (Sandbox Code Playgroud)

这完全行不通。任何帮助,将不胜感激。

ste*_*ver 16

由于 of 的退出状态grep指示是否找到匹配项,因此您应该能够直接将其作为find谓词进行测试(使用必要的否定!-not),例如

find . -type f -name "*.c" \( -exec grep -q "ABC" {} \; ! -exec grep -q "123" {} \; \) -print
Run Code Online (Sandbox Code Playgroud)

-q使得grep出口默默的第一场比赛-我们不需要从它听到的,因为我们让find打印的文件名。

  • @steeldriver:我相信你可以省略 `\(` 和 `\)`。 (2认同)

Sté*_*las 8

由于您已经在使用 GNU 扩展:

find . -type f -size +2c -name "*.c" -exec grep -l --null ABC {} + |
  xargs -r0 grep -L 123
Run Code Online (Sandbox Code Playgroud)

如果您想对这些文件执行其他操作:

find . -type f -size +2c -name "*.c" -exec grep -l --null ABC {} + |
  xargs -r0 grep -L --null 123 | xargs -r0 sh -c '
    for file do
      something with "$file"
    done' sh {} +
Run Code Online (Sandbox Code Playgroud)

或与zshbash

find . -type f -size +2c -name "*.c" -exec grep -l --null ABC {} + |
  xargs -r0 grep -L --null 123 |
  while IFS= read -rd '' file; do
    something with "$file"
  done
Run Code Online (Sandbox Code Playgroud)