How to find files that contain one criterion but exclude a different criterion

findgrep

I have a tree of source code and I am looking to find all files that contain a certain word and must not contain a second word. This, because I need to update older files to include some newer code.

I know I can use find, but I feel like if I try to chain grep statements it won't work because the second grep statement is going to be searching the results of the first and then I got lost.

I tried:

find . -type f -name "*.c" -exec grep -Hl "ABC" {} \; | grep -L "123"

And this totally did not work. Any help would be appreciated.

Best Answer

Since the exit status of grep indicates whether or not it found a match, you should be able to test that directly as a find predicate (with the necessary negation, ! or -not) e.g.

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

-q makes grep exit silently on the first match - we don't need to hear from it because we let find print the filename.

Related Question