![如何查找包含一个条件但排除另一条件的文件](https://linux22.com/image/96009/%E5%A6%82%E4%BD%95%E6%9F%A5%E6%89%BE%E5%8C%85%E5%90%AB%E4%B8%80%E4%B8%AA%E6%9D%A1%E4%BB%B6%E4%BD%86%E6%8E%92%E9%99%A4%E5%8F%A6%E4%B8%80%E6%9D%A1%E4%BB%B6%E7%9A%84%E6%96%87%E4%BB%B6.png)
我有一个源代码树,我正在寻找包含某个单词且不得包含第二个单词的所有文件。这是因为我需要更新旧文件以包含一些新代码。
我知道我可以使用 find,但我觉得如果我尝试链接 grep 语句,它将不起作用,因为第二个 grep 语句将搜索第一个 grep 语句的结果,然后我迷路了。
我试过:
find . -type f -name "*.c" -exec grep -Hl "ABC" {} \; | grep -L "123"
这完全行不通。任何帮助,将不胜感激。
答案1
由于 的退出状态grep
指示它是否找到匹配项,因此您应该能够直接将其作为find
谓词进行测试(带有必要的否定,!
或-not
),例如
find . -type f -name "*.c" \( -exec grep -q "ABC" {} \; ! -exec grep -q "123" {} \; \) -print
-q
在第一场比赛中静默grep
退出 - 我们不需要听到它的消息,因为我们让find
打印文件名。
答案2
由于您已经在使用 GNU 扩展:
find . -type f -size +2c -name "*.c" -exec grep -l --null ABC {} + |
xargs -r0 grep -L 123
如果您想对这些文件执行其他操作:
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 {} +
或者用zsh
or bash
:
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
答案3
对于复杂的约束,我更喜欢使用编程语言:Awk
find -name '*.c' \
-exec awk -v RS="\0" '/ABC/ && !/123/{print FILENAME}' {} \;