Unix/Linux grep
FAQ: How can I perform a recursive search with the grep command in Linux?
Two solutions are shown next, followed by some additional details which may be useful.
Solution 1: Combine 'find' and 'grep'
For years I always used variations of the following Linux find
and grep
commands to recursively search sub-directories for files that match a grep
pattern:
find . -type f -exec grep -l 'alvin' {} \;
This command can be read as, “Search all files in all sub-directories of the current directory for the string ‘alvin’, and print the filenames that contain this pattern.” It’s an extremely powerful approach for recursively searching files in all sub-directories that match the pattern I specify.
Here’s an explanation of those command-line arguments:
- The name of the command is
find
- The “
.
” means “current directory”
- The
-type f
part means “only search for files (not directories)”
-exec
means “execute the following command”
grep -l 'alvin'
is the command that searches the files for the string “alvin
”
- The
{} \;
part of the command is a little unusual ... I think it’s an old artifact of the find
command, but you can think of that area as holding each file that the find
command finds, and then grep
operates on each one of those files, one file at a time
Solution 2: 'grep -r'
However, I was just reminded that a much easier way to perform the same recursive search is with the -r
flag of the grep
command:
grep -rl alvin .
As you can see, this is a much shorter command, and it performs the same recursive search as the longer command, specifically:
- The
-r
option says “do a recursive search”
- The
-l
option (lowercase letter L) says “list only filenames”
- As you’ll see below, you can also add
-i
for case-insensitive searches
If you haven’t used commands like these before, to demonstrate the results of this search, in a PHP project directory I’m working in right now, this command returns a list of files like this:
./index.tpl
./js/jquery-1.6.2.min.js
./webservice/ws_get_table_names.php
More: How to search multiple sub-directories
Your recursive grep searches don’t have to be limited to just the current directory. This next example shows how to recursively search two unrelated directories for the case-insensitive string "alvin":
grep -ril alvin /home/cato /htdocs/zenf
In this example, the search is made case-insensitive by adding the -i
argument to the grep
command.
Using egrep recursively
You can also perform recursive searches with the egrep
command, which lets you search for multiple patterns at one time. Since I tend to mark comments in my code with my initials ("aja") or my name ("alvin"), this recursive egrep
command shows how to search for those two patterns, again in a case-insensitive manner:
egrep -ril 'aja|alvin' .
Note that in this case, quotes are required around my search pattern.
Summary: `grep -r` notes
A few notes about the grep -r
command:
- This particular use of the
grep
command doesn’t make much sense unless you use it with the -l
(lowercase "L") argument as well. This flag tells grep
to print the matching filenames.
- Don’t forget to list one or more directories at the end of your
grep
command. If you forget to add any directories, grep
will attempt to read from standard input (as usual).
- As shown, you can use other normal
grep
flags as well, including -i
to ignore case, -v
to reverse the meaning of the search, etc.
Here’s the section of the Linux grep
man page that discusses the -r
flag:
-R, -r, --recursive
Read all files under each directory, recursively; this is
equivalent to the -d recurse option.
--include=PATTERN
Recurse in directories only searching file matching PATTERN.
--exclude=PATTERN
Recurse in directories skip file matching PATTERN.
As you’ve seen, the grep -r
command makes it easy to recursively search directories for all files that match the search pattern you specify, and the syntax is much shorter than the equivalent find/grep command.
For more information on the find
command, see my Linux find command examples, and for more information on the grep
command, see my Linux grep command examples.