Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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?

share|improve this question
up vote 6 down vote accepted

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' .
share|improve this answer
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 posting your answer, you agree to the privacy policy and terms of service.

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