How to combine find and grep to recursively search for str or str2 in *.html and *.php files from /home/smith/sourcecode?

2

2

How can i combine find and grep to search for str1 or str2, recursively, in all *.html and *.php files starting from a directory named /home/smith/source? The output only needs to list files (with path), not the actual matched string. i've tried many variations without success. There are lots of examples of how to do this for one file pattern or one string, but not multiple file patterns and multiple strings--recursively.

Ascoobis

Posted 2013-03-29T00:40:17.317

Reputation:

Answers

4

Others are all correct, but with a modern version of grep available they are overkill in my opinion. The following will recursively scan only files with .html or .php extensions and return the filename with path of each file with at least one line matching either str1 or str2. Note that the repeated -e options allow specification of multiple paths without using regex syntax to do so.

grep -r --files-with-matches --include '.html' --include '.php' -e str1 -e str2 /home/smith/source

One tool, one process, no extra forking or scanning of non-relevant files. Just requires a relatively recent version of gnu grep for the --include option, failing that you will have to do a multi-stage grep as proposed by others.

Tom Scogland

Posted 2013-03-29T00:40:17.317

Reputation: 166

3

egrep 'string1|string2' /home/smith/source/*.{html,php}

or looking into any type of file recursively inside a directory,

egrep -R 'string1|string2' /home/smith/source

you can combine that with another egrep in the pipe :

egrep -R 'string1|string2' /home/smith/source | egrep '.html|.php'

iamauser

Posted 2013-03-29T00:40:17.317

Reputation: 155

1

Use egrep and use | to specify str1 or str2-:

find /home/smith/source -name \*.html -o -name \*.php -exec egrep -H 'str1|str2' {} \;

suspectus

Posted 2013-03-29T00:40:17.317

Reputation: 3 957

That shows matched text, not filenames, but that's OK (I made the update to the questions probably while you were answering the existing one). How can I generalize this if i want to search 3,4,5, or n file patterns? – None – 2013-03-29T01:02:23.923

-H option of egrep then to output filepaths. str1|str2|str3..etc would work - is that what you mean by generalize? – suspectus – 2013-03-29T01:06:37.687

Yes, but I also meant to generalize the file pattern (e.g., *.php and *.html and .txt and ...). This appears to do it: `find /home/smiths/source -type f -regextype posix-egrep -regex "..(php|html)$" -exec egrep -H -n "str1|str2|str3" '{}' ;` – None – 2013-03-29T01:42:26.157

1

If you use ack (see http://beyondgrep.com) you can do this:

ack --php --html -l 'str1|str2' /home/smith/source

Andy Lester

Posted 2013-03-29T00:40:17.317

Reputation: 1 121

Also reimplemented as ag and rg. Which I think is a testament to its musthaveness.

– user2394284 – 2016-12-22T22:49:36.883

Reimplemented by a number of different tools, many of which are listed here: http://beyondgrep.com/more-tools/

– Andy Lester – 2016-12-23T22:07:42.607

0

Don't forget that your shell is way more convenient than find if you only want to find the files by name!

Bash:

shopt -s nullglob globstar
grep -lE 'str1|str2' /home/smith/source/**/*.{html,php}

Fish:

grep -lE 'str1|str2' /home/smith/source/**.{html,php}

user2394284

Posted 2013-03-29T00:40:17.317

Reputation: 871