Linux / UNIX Recursively Search All Files For A String

last updated in Categories , , , , , , , , ,

How do I recursively search all text files for a string such as foo under UNIX / Linux / *BSD / Mac OS X shell prompt?

You can use grep command or find command as follows.


grep command: Recursively Search All Files For A String

The syntax is:
cd /path/to/dir
grep -r "word" .

grep -r "string" .
To ignore case distinctions:
grep -ri "word" .
To display print only the filenames with GNU grep, enter:
grep -r -l "foo" .
You can also specify directory name:
grep -r -l "foo" /path/to/dir/*.c

find command: Recursively Search All Files For A String

find command is recommend because of speed and ability to deal with filenames that contain spaces.

cd /path/to/dir
find . -type f -exec grep -l "word" {} +
find . -type f -exec grep -l "seting" {} +
find . -type f -exec grep -l "foo" {} +
find /search/dir/ -type f -name "*.c" -print0 | xargs -I {} -0 grep "foo" "{}"
## Search /etc/ directory for 'nameserver' word in all *.conf files ##
find /etc/ -type f -name "*.conf" -print0 | xargs -I {} -0 grep "nameserver" "{}"

Older UNIX version should use xargs to speed up things:
find /path/to/dir -type f | xargs grep -l "foo"
It is good idea to pass -print0 option to find command that it can deal with filenames that contain spaces or other metacharacters:
find /path/to/dir -type f -print0 | xargs -0 grep -l "foo"
OR use the following OSX/BSD/find or GNU/find example:

find /path/to/dir/ -type f -name "file-pattern" -print0 | xargs -I {}  -0 grep -l "search-term" "{}"
## OR ##
find /mycool/project/ -type f -name "*.py" -print0 | xargs -I {}  -0 grep -H --color "methodNameHere" "{}"
## OR search all files in /etc/ dir for 'nameserver' word ##
find /etc/ -iname "*" -type f -print0  |  xargs -0 grep -H "nameserver"

Sample outputs from the last command:

Fig.01: Unix and Linux: How to Grep Recursively?
Fig.01: Unix and Linux: How to Grep Recursively?


Posted by: Vivek Gite

The author is the creator of nixCraft and a seasoned sysadmin, DevOps engineer, and a trainer for the Linux operating system/Unix shell scripting. Get the latest tutorials on SysAdmin, Linux/Unix and open source topics via RSS/XML feed or weekly email newsletter.

22 comment

  1. That is fantastic, a command that says it does exactly what I’m looking for.

    Unfortunately, when I copy and paste the example to recursivle search for files containing a string:
    find . -type f -exec grep -l “word” {} +

    in to my linux session I get a set of error message lines which all say this:

    find: grep: Argument list too long

    To fix this, simply add the following to hide any such error messages by oplacing them in the trash:

    find . -type f -exec grep -l “word” {} + 2>>/dev/null

  2. Perfect, had to search a joomla install for all occurrences of a string, used grep as i remember if from my uni days, thanks for the post.


  3. it won’t work if you are trying to search for:

    grep -r “test!!!” .

    you need to use the single quotations. like:

    grep -r ‘test!!!’ .

  4. Would you let me know how to add a grep -v to the search , so i can supress some unwanted files?


  5. This is indeed great. Now I wanted to shortcut this expression by putting it into my .bash_profile file as an alias but I can’t get that too work. I’ve tried a lot of variations on this theme:

    alias f=”find . -type f -exec grep -l $1 {} +”

    but then when I type something like “f foobar” it responds with “find: foobar: unknown option”. I’m sure this is stupidly easy but I’ve tried enough variations I thought I’d ask for some help.

    1. You can not pass args to alias. Use bash shell function:

      f(){ find . -type f -exec grep -l $1 {} + ; }

      Run it as:

      f foobar

      Hope this helps!

  6. Actually, using find to grep files is way slower than using grep -r. Try it, go into a folder with a whole bunch of files (hundreds, if not more), and run:

    date ; find . -type f -exec grep somestring {} \; ; date

    and then:

    date ; grep -r somestring . ; date

    The first operation took me about 10 seconds. The second one took about 3-4 seconds.

  7. Also, it’s helpful to use the “-n” flag to show the line number of the file the text is on.

    Still, have a question? Get help on our forum!