17

To find all the files that contain "foo" in current folder, I use:

grep -r "foo" . 

To find all the files that contain "bar" in current folder, I use:

grep -r "bar" . 

But how to find all files that does not contain 'foo' and 'bar'?

6 Answers 6

27

To print lines that do not contain some string, you use the -v flag:

grep -r -v "bar" . | grep -v "foo" 

This gives you all lines that do not contain foo or bar.

To print files that do not contain some string, you use the -L flag. To non-match several strings, you can use regular expressions with the -P flag (there are several regex flags you can use):

grep -r -L -P "(foo|bar)" . 

This prints a list of files that don't contain foo or bar.

Thanks to Anton Kovalenko for pointing this out.

Sign up to request clarification or add additional context in comments.

4 Comments

Wrong. -v is about non-matching lines being present, not about matching lines being absent.
@AntonKovalenko You're right, I removed the -r in the pipe. For the "non-matching lines", that's what the OP is asking for: grep -v "foo" goves lines that do not match foo.
He asks about files that don't contain foo and bar at all, not about files that contain some non-bar lines and some non-foo lines.
@AntonKovalenko Oh of course, I just got the subtility, I read a bit too fast.
7

Recursively searches directories for all files that do no contains XYZ

find . -type f | xargs grep -L "XYZ" 

1 Comment

I tried your solution and the result is the opposite. I got all files that contained XYZ.
4

Try this one:

 grep -L -e "foo\|bar" * 

Comments

2

With awk, something like:

awk 'BEGIN {f=ARGV[1] ; ff=0} f != FILENAME { if ( ff>0 ) { print f } ; ff=0 ; f=FILENAME } /SEARCHSTRING/ {ff=1} END {if ( ff>0 ) { print f } }' INPUT_FILE_LIST(PATTERN) 

Basically it reads every input file and if sees your SEARCHSTRING (which can be a regex), it saves that info. After finishing the current file (or after the last file), check if it found something, and if so, print the previous filename.

2 Comments

I love this over the grep-answers because I can easily specify in which files to search. Looking for all files that do not import xy is much more noisy than looking for all *.py **/*.py files not containing an import.
I do not understand how 'print the previous filename if match is found in the current file' solves the question at all. I have confirmed on my files that the results of this are wrong.
2

Try the below. this should work

grep -rL -P "(foo|bar)" .

Comments

0

In case you need to find files with a specific extension (or name pattern) not containing a string (or pattern):

find . -name "*.ext" | xargs -n1 grep -r -L -P "(foo|bar)" 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.