Bash Grep Subdirectories (Recursively)

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/dir

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

grep -r "" /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

🐧 Get the latest tutorials on Linux, Open Source & DevOps via RSS feed or Weekly email newsletter.

🐧 4 comments so far... add one

CategoryList of Unix and Linux commands
Disk space analyzersdf duf ncdu pydf
File Managementcat cp mkdir tree
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Modern utilitiesbat exa
Network UtilitiesNetHogs dig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg glances gtop jobs killall kill pidof pstree pwdx time vtop
Searchingag grep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
4 comments… add one
  • Lev Elbert Jul 9, 2012 @ 19:17

    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).

  • Jon Oñativia Nov 27, 2012 @ 12:19

    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’

  • P.Thompson Apr 14, 2014 @ 15:43

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

  • Nigel Allen May 29, 2014 @ 4:51

    Of course, you could just learn how to use it the shell and escape the wildcards when you specifically don’t want them .

Leave a Reply

Your email address will not be published.

Use HTML <pre>...</pre> for code samples. Still have questions? Post it on our forum