Differences between revisions 9 and 13 (spanning 4 versions)
Revision 9 as of 2009-12-29 17:44:22
Size: 1609
Editor: MatthiasPopp
Comment:
Revision 13 as of 2014-04-22 00:13:35
Size: 1748
Editor: GreyCat
Comment: a few notes
Deletions are marked like this. Additions are marked like this.
Line 3: Line 3:
90% of the time, all you need is one of these: If you are on a typical GNU or BSD system, all you need is one of these:
Line 7: Line 7:
grep -r "$search" . grep -r -- "$search" .
Line 10: Line 10:
grep -r -l "$search" . grep -r -l -- "$search" .
Line 13: Line 13:
You can use [[UsingFind|find]] if your {{{grep}}} lacks a {{{-r}}} option: If your `grep` lacks a `-r` option, you can [[UsingFind|use find]] to do the recursion:
Line 15: Line 16:
find . -type f -exec grep -l "$search" {} \; # Portable but slow
find . -type f -exec grep -l -- "$search" {} \;
Line 18: Line 20:
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:
Line 20: Line 22:
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 22: Line 23:
find . -type f -exec grep -l "$search" {} + # Fast, but requires a recent find
find . -type f -exec grep -l -- "$search" {} +
Line 24: 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, as well as ''very'' recent GNU {{{find}}}.
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-2008 {{{find}}}, which ''most'' current operating systems have, but which may not be available on legacy systems.
Line 28: Line 29:
Line 29: Line 31:
find . -type f | xargs grep -l "$seach" # DO NOT USE THIS
find . -type f | xargs grep -l -- "$search"
Line 31: Line 34:
However, if your filenames contain spaces, quotes or other metacharacters, this will fail catastrophically. BSD/GNU `xargs` has a `-print0` option:
Line 32: Line 36:
However, if your filenames contain spaces or other metacharacters, you'll need to use the BSD/GNU {{{-print0}}} option:
Line 34: Line 37:
find . -type f -print0 | xargs -0 grep -l "$search" find . -type f -print0 | xargs -0 grep -l -- "$search"
Line 36: Line 39:

How can I recursively search all files for a string?

If you are on a typical GNU or BSD system, 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" .

If your grep lacks a -r option, you can use find to do the recursion:

# Portable but slow
find . -type f -exec grep -l -- "$search" {} \;

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:

# Fast, but requires a recent find
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-2008 find, which most current operating systems have, but which may not be available on legacy systems.

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

# DO NOT USE THIS
find . -type f | xargs grep -l -- "$search"

However, if your filenames contain spaces, quotes or other metacharacters, this will fail catastrophically. BSD/GNU xargs has a -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.


CategoryShell

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