bhttoan
bhttoan

Reputation: 2736

Using find recursively and only returning the matching file names

I am trying to find all instances of a string within files - I am using find and it works great, however, it returns not only the file but every instance of that string within the file which results in a huge long list whereas I really only want the file name.

I am using:

find . -name '*.php' -exec grep -i 'MATCH' {} \; -print

This will show me every instance of MATCH and then the file name then the next batch and the filename so something like:

MATCH
MATCH
MATCH
./filename
MATCH
MATCH
MATCH
./filename2

I tried changing GREP to:

find . -name '*.php' -exec grep -H -i 'MATCH' {} \; -print

and this then gave me:

./filename: MATCH
./filename: MATCH
./filename: MATCH
./filename2: MATCH
./filename2: MATCH
./filename2: MATCH

however this still results in the same number of lines being shown all be it slightly differently laid out.

I tried changing GREP to:

find . -name '*.php' -exec grep -l -i 'MATCH' {} \; -print

and this then gave me:

./filename
./filename
./filename
./filename2
./filename2
./filename2

Ideally I would like something like:

./filename
./filename2

which only lists each of the file which match once regardless of how many times it appears in each file - can this be done?

Upvotes: 1

Views: 864

Answers (2)

Ed Morton
Ed Morton

Reputation: 203995

It's not the grep that's the problem, you're telling find to print every file name:

find . -name '*.php' -exec grep -l -i 'MATCH' {} \; -print

Note the -print at the end. Just remove that:

find . -name '*.php' -exec grep -l -i 'MATCH' {} \;

Look:

$ echo 'foo' > file1

$ echo 'foo' > file2

$ find . -name 'file*' -exec grep -l -i foo {} \; -print
./file1
./file1
./file2
./file2

$ find . -name 'file*' -exec grep -l -i foo {} \;
./file1
./file2

Upvotes: 0

Yunnosch
Yunnosch

Reputation: 26753

Use the features provided by grep:

-l, --files-with-matches print only names of FILEs containing matches
-R, -r, --recursive equivalent to --directories=recurse
--include=FILE_PATTERN search only files that match FILE_PATTERN
-i, --ignore-case ignore case distinctions

I.e.

grep -ril --include="*.php" 'MATCH' .

Upvotes: 2

Related Questions