Combine find with bash -c instead of a script. We take file path and store it into file variable, then pass it further to other commands. First grep -q will check if there is one word/pattern that you want is present. Using its exit status, && will pass it on to second grep -q. If that command doesn't find a match, that means the string is not found, thus using its exit status , we pass it on to echo via || operator.
In the example below, only file2.txt contains abra but not cadabra word.
$ find -type f -exec bash -c 'file="$@";grep -q "abra" "$file" && grep -q "cadabra" "$file" || echo "$file" ' sh "{}" >
./file2.txt
$ ls
file1.txt file2.txt file 3.txt
$ cat file1.txt
abra cadabra
$ cat file2.txt
abra
$ cat file\ 3.txt
abra cadabra
grep -r ... --null ... wanted-strpiped to "xargs --null grep -v unwanted-str" (assuming GNU grep & xargs, for the null support) – Jeff Schaller Jan 16 '17 at 16:17grep being line based, conditions such as grep -q printf file && grep -vq '#include <stdio.h>' file will not workWhile grep is line matching tool, it supports regular expressions for matching specific words and patterns. It really depends on what you want to do with it. – Sergiy Kolodyazhnyy Jan 16 '17 at 16:27grep -Lto get files that do not contain a match. You can also add-q:-qis line based-Lis file based. – ctrl-alt-delor Jan 16 '17 at 17:04