Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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.

share|improve this question

6 Answers 6

up vote 10 down vote accepted

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):

--directories=action
    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. 
--exclude=glob
    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. 
--exclude-from=file
    Skip files whose base name matches any of the file-name globs read from 
    file (using wildcard matching as described under ‘--exclude’). 
--exclude-dir=dir
    Exclude directories matching the pattern dir from recursive directory 
    searches. 
-I
    Process a binary file as if it did not contain matching data; this is 
    equivalent to the ‘--binary-files=without-match’ option. 
--include=glob
    Search only files whose base name matches glob (using wildcard matching 
    as described under ‘--exclude’). 
-r
-R
--recursive
    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.
--with-filename
    Print the file name for each match. This is the default when there is 
    more than one file to search. 
share|improve this answer
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

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
share|improve this answer

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.

share|improve this answer

I use:

find . -name 'whatever*' -exec grep -H searched_string {} \;
share|improve this answer

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.

share|improve this answer

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;
share|improve this answer
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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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