Linux / UNIX Recursively Search All Files For A String

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.

ADVERTISEMENTS

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?

🐧 Get the latest tutorials on SysAdmin, Linux/Unix, Open Source/DevOps topics:
CategoryList of Unix and Linux commands
File Managementcat
Network Utilitiesdig host ip nmap
Package Managerapk apt
Processes Managementbg chroot disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w

ADVERTISEMENTS
22 comments… add one
  • rjbcollege May 27, 2010 @ 10:08

    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

  • Pete Shore Jul 25, 2010 @ 10:51

    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.

    Pete

  • lanh May 14, 2011 @ 17:37

    Thank you this was very useful for debugging!

  • Radhakrishnan Jul 12, 2011 @ 7:06

    This tutorial is very useful .

  • Fernando Lopez Jr. Oct 2, 2011 @ 1:24

    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!!!’ .

  • jinil Feb 15, 2012 @ 4:51

    How can I recursively search all files for 2 strings?
    I mean, files containing both strings..

    Thanks :)

    • Ben May 17, 2015 @ 0:28

      You can pipe one grep into another.

    • bob Oct 8, 2016 @ 21:13

      grep -r -e string1 -e string2 /

  • analytical Feb 21, 2012 @ 15:28

    Thanks, changed my default web directory somewhere and now I don’t know where. This will help.

  • mica Mar 30, 2012 @ 15:40

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

    thanks

    • bob Oct 8, 2016 @ 21:21

      find . -not -name “*.svn” -not -name “*.git -exec grep -e string1 -e string2 {} \;

  • Ken Apr 6, 2012 @ 22:17

    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.

    • 🐧 nixCraft Apr 7, 2012 @ 10:24

      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!

  • Ken Apr 10, 2012 @ 16:55

    Great thanks Vivek!

  • Arsie May 28, 2012 @ 3:23

    Thanks for this information, I was able to get the file I am looking for on my box.

  • CaptSaltyJack May 14, 2013 @ 3:29

    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.

  • perfect tutorial Feb 26, 2014 @ 5:01

    Great article! Just another reason why *nix should be embraced for ever.

  • Joshua Pinter Mar 21, 2014 @ 19:44

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

  • Igor Sep 24, 2015 @ 19:38

    Awesome!
    grep -ri “word” .
    grep -ri -l “word” .
    thanks a lot.

  • Ranjeet Jan 20, 2016 @ 8:45

    Thank you very much for this find command

  • tpro Oct 8, 2016 @ 16:16

    Definitely better and faster tool is ack-grep package

  • Jon Oct 8, 2016 @ 17:40

    How can the command be modified to search sub folders as well?

Leave a Reply

Your email address will not be published.

Use HTML <pre>...</pre>, <code>...</code> and <kbd>...</kbd> for code samples.