Bash Grep Subdirectories (Recursively)

by on February 17, 2007 · 3 comments· LAST UPDATED February 17, 2010

in

How do I recursively grep through all sub-directories and find files containing given text / string or words?

You can use the -r option to recursively grep through all sub-directories and find text. The syntax is as follows:

grep -r "text" /path/to/di

In this example, search for an IP 192.168.1.254 in through all /etc/ and all its sub-directories:

grep -r "192.168.1.254" /etc/

Search in any case:

grep -ri "letters" /home/vivek/data

Use the -l switch to display only the names of files in which the text occurs:

grep -lri "foo" /data
TwitterFacebookGoogle+PDF versionFound an error/typo on this page? Help us!

{ 3 comments… read them below or add one }

1 Lev Elbert July 9, 2012 at 7:17 pm

Grep does allow recursive search, but only if you don’t specify the files you are looking for. For example:
grep -r ‘ActiveServer’ . works, but outputs a lot of noise (like log and binary files)

grep -r ‘ActiveServer’ *.java will tell something like:
“zsh: no matches found: *.java”

A “quick and dirty” way to solve the problem:
grep -r ‘ActiveServer’ . | grep ‘.java:’
This still might output some non-java entries.
But this doesn’t ():
grep -rl ‘ActiveServer’ . | grep ‘.java’

I usually run this command and a separate terminal tab (or window).

Reply

2 Jon Oñativia November 27, 2012 at 12:19 pm

When I want to grep over files with a specific extension in a file tree I do it combining it with “find”:
$ find . -name \*.java | xargs grep ‘ActiveServer’

Reply

3 P.Thompson April 14, 2014 at 3:43 pm

See, this is why sometimes *nix really sucks. For over 15 years I’ve used the Borland version of grep on Windows which does recursive searches through subdirectories in files specified by wildcard filenames, and it works fine, intuitively and logically.

For example, to search all .css files in the branch of a project for the word “header”, you can type:

grep -r “header” *.css

…and grep recurses through all subdirectories only searching files that match *.css
…no muss, no fuss, no screwing around with bizarre tool things and contorted syntax

But it’s not *nix grep’s fault — the fault is the design of the *nix file system and command line expansion. The expansion of wildcard filenames inline rather than passing the wildcard descriptor to the programs for traversal is one of the most doofus features of *nix. I don’t know how many programmers have been burned by this “feature” when they typed something like:

compile *.c

and the compile broke because the inline expanded filenames broke the piping system. This rinky-dink way of working is fine for toy programs and projects, but it’s a pain in the butt when you try to do anything of size. A large real project could have on the order of 50-100 libraries, each with 10-1000 program files. The make facility was created to get around this limitation.

Whereas on the old PDP-10, with the OS and programs running in less than 10 megabytes of memory, you could type

compile *.c

and it would just do it. You could also type

link *.c
or
execute *.c

and it was smart enough to look at the file times and dates, compile what it needed to, link object modules and libraries, and even begin execution, all without need for a make facility.

I use both *nix and MS operating systems, they both have good and bad things about them. Someday someone should fix that wildcard file situation with some future version of *nix, but I think it’s gonna take a complete re-roll of the OS.

Reply

Leave a Comment

Tagged as: , , , , , , , , , , , ,

Previous Faq:

Next Faq: