Is there some sophisticated technique to search strings in many files?

I tried this basic technique

for i in `find .`; do grep searched_string "$i"; done;

It doesn't look much sophisticated and moreover it has found nothing in hierarchy of files.


You can do either of

grep pattern_search . # does a normal grep on the current directory

grep pattern_search * # use a normal grep on all the globbed files from the current directory

grep -R pattern_search . # use a recursive search on the current directory

grep -H pattern_search * # prints filename when the files are more than one. ‘-H’

Other options such as (from gnu manual):

    If an input file is a directory, use action to process it. By default, 
    action is ‘read’, which means that directories are read just as if they 
    were ordinary files (some operating systems and file systems disallow 
    this, and will cause grep to print error messages for every directory 
    or silently skip them). If action is ‘skip’, directories are silently 
    skipped. If action is ‘recurse’, grep reads all files under each 
    directory, recursively; this is equivalent to the ‘-r’ option. 
    Skip files whose base name matches glob (using wildcard matching). A 
    file-name glob can use ‘*’, ‘?’, and ‘[’...‘]’ as wildcards, and \ to 
    quote a wildcard or backslash character literally. 
    Skip files whose base name matches any of the file-name globs read from 
    file (using wildcard matching as described under ‘--exclude’). 
    Exclude directories matching the pattern dir from recursive directory 
    Process a binary file as if it did not contain matching data; this is 
    equivalent to the ‘--binary-files=without-match’ option. 
    Search only files whose base name matches glob (using wildcard matching 
    as described under ‘--exclude’). 
    For each directory mentioned on the command line, read and process all 
    files in that directory, recursively. This is the same as the 
    --directories=recurse option.
    Print the file name for each match. This is the default when there is 
    more than one file to search. 
  • 4
    The first form, grep pattern . do not search any file, without the recursive option. – enzotib Dec 5 '11 at 13:07
  • 1
    grep is much faster than find. – Nils Dec 5 '11 at 20:46

I use:

find . -name 'whatever*' -exec grep -H searched_string {} \;

Building on Chris Card's answer, I myself use: find . -print0 | xargs -r0 grep -H searched_string The -print0 combined with -0 in xargs ensures that whitespace in filenames is handled properly. The -r tells xargs to give at least one filename on the command-line. I also generally use fgrep if I want fixed strings (no regular expression), which is a little faster.

Using find . -print0 | xargs -0 cmd is faster than find . -exec cmd {} \;. It is slightly slower than find . -exec cmd {} +, but more widely available then the -exec+ usage.


Check out ack-grep. It's perfect for quick searches, and gets bonus points for ignoring .svn-directories by default. It outputs the file-name and the line-number on where the string was found.

ack-grep -a Fnord

If you add a /dev/null in your command you will also get the file name where the string is matched:

for i in `find .`; do grep searched_string "$i" /dev/null ; done;
  • 1
    Or use grep's -H aka --with-filename option. – James McLeod Dec 5 '11 at 12:05
  • 1
    for i in $(find .) should be definitively avoided (I used the equivalent syntax $() instead of backticks because they conflict with formatting delimiters). It breaks on filenames with spaces. – enzotib Dec 5 '11 at 13:26

A pattern not mentioned yet is :

find . -name "<filename>" | xargs grep "<>"

As in

find . -name Makefile | xargs grep -v "target"

to find in all your Makefiles which is missing a particular target.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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