There must be a better / shorter way to do this:
# Find files that contain in current directory
# (including sub directories)
$ find .
If this is going to be a common search utility you're going to utilize, you may want to take a look at ack, which combines both the find and the grep together into this functionality that you're looking for. It has fewer features than grep, though 99% of my searches are suited perfectly by replacing all instances of grep with ack.
Besides the other answers given, I also suggest this construct:
Even better, if the filenames have spaces in them, you can either quote
find . -type f -name "*.html" -print|xargs -I FILENAME grep "< string-to-find>" FILENAME
"FILENAME" or pass a null-terminated (instead of newline-terminated) result from find to xargs, and then have xargs strip those out itself:
find . -type f -name "*.html" -print0|xargs -0 -I FILENAME grep "< string-to-find>" FILENAME
here --^ and --^
Here, the name FILENAME can actually be anything, but it needs to match both
Like this:
find . -type f -name "*.html" -print0|xargs -0 -I FILENAME grep "< string-to-find>" FILENAME
here --^ and --^
find . -type f -name "*.html" -print0|xargs -0 -I GRRRR grep "< string-to-find>" GRRR
this --^ this --^
It's essentially doing the same thing as the {} used within the find statement itself to state "the line of text that this returned". Otherwise, xargs just tacks the results of find to the END of all the rest of the commands you give it (which doesn't help much if you want grep to search inside a file, which is usually specified last on the command-line).