Differences between revisions 1 and 7 (spanning 6 versions)
Revision 1 as of 2007-05-02 22:52:21
Size: 1828
Editor: redondos
Comment:
Revision 7 as of 2008-11-22 14:08:37
Size: 1588
Editor: localhost
Comment: converted to 1.6 markup
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
[[Anchor(faq8)]] <<Anchor(faq8)>>
Line 3: Line 3:
On most recent systems (GNU/Linux/BSD), you would use {{{grep -r pattern .}}} to search all files from the current directory (.) downward.
Line 5: Line 4:
You can use {{{find}}} if your {{{grep}}} lacks -r: 90% of the time, all you need is one of these:
Line 7: Line 7:
    find . -type f -exec grep -l "$search" '{}' \; # Recurse and print matching lines (GNU grep):
grep -r "$search" .

# Recurse and print only the filenames (GNU grep):
grep -r -l "$search" .
}}}

You can use [[UsingFind|find]] if your {{{grep}}} lacks a {{{-r}}} option:
{{{
find . -type f -exec grep -l "$search" {} \;
Line 12: Line 21:
This command is slower than it needs to be, because {{{find}}} will call {{{grep}}} with only one file name, resulting in many {{{grep}}} invocations (one per file). Since {{{grep}}} accepts multiple file names on the command line, {{{find}}} can be instrumented to call it with several file names at once: This command is slower than it needs to be, because {{{find}}} will call {{{grep}}} with only one file name, resulting in many {{{grep}}} invocations (one per file). Since {{{grep}}} accepts multiple file names on the command line, {{{find}}} can be instructed to call it with several file names at once:
Line 14: Line 23:
    find . -type f -exec grep -l "$search" '{}' \+ find . -type f -exec grep -l "$search" {} +
Line 17: Line 26:
The trailing '+' character instructs {{{find}}} to call {{{grep}}} with as many file names as possible, saving processes and resulting in faster execution. This example works for POSIX {{{find}}}, e.g. with Solaris. The trailing '+' character instructs {{{find}}} to call {{{grep}}} with as many file names as possible, saving processes and resulting in faster execution. This example works for POSIX {{{find}}}, e.g. with Solaris, as well as ''very'' recent GNU {{{find}}}.
Line 19: Line 28:
GNU find uses a helper program called {{{xargs}}} for the same purpose: Traditional Unix has a helper program called {{{xargs}}} for the same purpose:
Line 21: Line 30:
    find . -type f -print0 | xargs -0 grep -l "$search" find . -type f | xargs grep -l "$seach"
Line 24: Line 33:
The {{{-print0}}} / {{{-0}}} options ensure that any file name can be processed, even ones containing blanks, TAB characters, or new-lines.

90% of the time, all you need is:

Have grep recurse and print the lines (GNU grep):
However, if your filenames contain spaces or other metacharacters, you'll need to use the BSD/GNU {{{-print0}}} option:
Line 30: Line 35:
    grep -r "$search" . find . -type f -print0 | xargs -0 grep -l "$search"
Line 33: Line 38:
Have grep recurse and print only the names (GNU grep):
{{{
    grep -r -l "$search" .
}}}

The {{{find}}} command can be used to run arbitrary commands on every file in a directory (including sub-directories). Replace {{{grep}}} with the command of your choice. The curly braces {} will be replaced with the current file name in the case above.

(Note that they must be escaped in some shells, but not in ["BASH"].)
The {{{-print0}}} / {{{-0}}} options ensure that any file name can be processed, even one containing [[BashFAQ/020|blanks, TAB characters, or newlines]].

How can I recursively search all files for a string?

90% of the time, all you need is one of these:

# Recurse and print matching lines (GNU grep):
grep -r "$search" .

# Recurse and print only the filenames (GNU grep):
grep -r -l "$search" .

You can use find if your grep lacks a -r option:

find . -type f -exec grep -l "$search" {} \;

The {} characters will be replaced with the current file name.

This command is slower than it needs to be, because find will call grep with only one file name, resulting in many grep invocations (one per file). Since grep accepts multiple file names on the command line, find can be instructed to call it with several file names at once:

find . -type f -exec grep -l "$search" {} +

The trailing '+' character instructs find to call grep with as many file names as possible, saving processes and resulting in faster execution. This example works for POSIX find, e.g. with Solaris, as well as very recent GNU find.

Traditional Unix has a helper program called xargs for the same purpose:

find . -type f | xargs grep -l "$seach"

However, if your filenames contain spaces or other metacharacters, you'll need to use the BSD/GNU -print0 option:

find . -type f -print0 | xargs -0 grep -l "$search"

The -print0 / -0 options ensure that any file name can be processed, even one containing blanks, TAB characters, or newlines.

BashFAQ/008 (last edited 2015-03-05 00:24:46 by izabera)