Basic grep question.

Following simple problem.
Find all files ending on ".txt" in the current directory tree and subdirectories, which contain the word "hello", and print their names.
Can it be done with grep or do you need , find,xargs,grep ?
 
grep -rl hello .|grep \\.txt$
but find is better
find . -iname \*.txt -print0 |xargs -0 grep -l hello

the 1st command will search in all files regardless of the extension and then filter only txt files
 
Find all files ending on ".txt" in the current directory tree and subdirectories, ...
Grep can't help with the list of files. Grep is a program, and it is passed a list of files by whatever executes it. Typically that is a shell. Most shells only have a mechanism for glob expansion in a directory, and in enumerated lists of subdirectories. So you can do "grep *.txt" for the current directory, "grep *.txt foo/*.txt" to add all text files in subdirectory foo, or "grep *.txt */*.txt" to add all text file in all subdirectories. But what that does not cover is recursion: It will not find foo/bar/*.txt, nor foo/bar/blatz/... and so on. I vaguely remember that there was one shell that used "**" to stand for "all subdirectories recursively down", but I don't remember which one.

So if you want to recurse infinitely far down, you'll have to use something like find (and perhaps xargs). Personally, I like the "find . -name \*.txt -print0 | xargs -0 grep -l hello" idiom more intelligible than "find . -name \*.txt -exec fgrep -l hello {}", but that's a question of taste.
 
xargs is better than exec because the number of spawned children is (sometimes a lot) less
and you can control this with xargs -n
 
Seriously, I think VladiBG is right: Looking at the man page for grep, it can recurse down directories with "-r", and it has an include switch to select files when running on whole directories. So it has "find" sort of built in. Didn't know that.
 
Back
Top