I search my code base to find string patterns and list all the files where the pattern is found but only the file and not the lines on which it is found:

find . -name *.java -exec grep -l 'someText' {} \; -print 2>/dev/null

However, it outputs two lines for each file found. Why does that happen and how should I modify the command to list unique file names?


grep prints files names AND returns a True/False value; if the value is True, then the -print action prints the file. So you have two possibilities:

find . -name '*.java' -exec grep -l 'someText' {} \;  2>/dev/null


find . -name '*.java' -exec grep -q 'someText' {} \; -print 2>/dev/null

And remember to quote *.java. Otherwise the shell may expand it to the list of java files in the current directory.

Also note you don't have to run one grep per file, you'd better do:

find . -name '*.java' -exec grep -l 'someText' {} +  2>/dev/null

Note the 2>/dev/null suppresses the errors of both find and grep. If you only want to make grep quiet, you can write it instead:

find . -name '*.java' -exec grep -sl 'someText' {} +

And last, note that the GNU implementation of grep can also do find's job:

grep -slr --include='*.java' 'someText' .
  • Thanks Stephane for your edit; your contribution in this answer is now more important and better than mine! It could not be more comprehensive. – JPG Feb 7 '14 at 12:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.