grep linux unix

How do I recursively grep all directories and subdirectories?


How do I recursively grep all directories and subdirectories?

find . | xargs grep "texthere" *


  • 131

    @TC1 The sad thing is that grep itself can answer the question (at least GNU grep): grep –help |grep recursive

    Oct 25, 2013 at 14:42

  • 10

    If you find yourself frequently using grep to do recursive searches (especially if you manually do a lot of file/directory exlusions), you may find ack (a very programmer-friendly grep alternative) useful.

    Oct 25, 2013 at 20:56

  • 25

    Actually neither -r nor –recursive work on the Solaris box I use at work. And the man page for grep doesn’t mention anything recursive. I had to resort to find and xargs myself.

    – Ben

    Jan 9, 2014 at 15:59

  • 9

    ag is my favorite way to do this now

    – dranxo

    May 21, 2014 at 23:11

  • 2

    grep -rin xlsx *.pl doesn’t work for me on Redhat Linux. I get a “no match” error.

    – Bulrush

    Sep 15, 2015 at 18:43


grep -r "texthere" .

The first parameter represents the regular expression to search for, while the second one represents the directory that should be searched. In this case, . means the current directory.

Note: This works for GNU grep, and on some platforms like Solaris you must specifically use GNU grep as opposed to legacy implementation. For Solaris this is the ggrep command.


  • 44

    Note: “grep -r” only works on newer greps. It doesn’t work on the grep that comes with AIX 5.3 for example.

    – Withheld

    Feb 1, 2013 at 13:09

  • 131

    Use grep -R to follow symlinks.

    – Eloff

    Apr 5, 2013 at 23:01

  • 67

    It is good to know that “-i” would make it case insensitive, and “-n” also include the line number for each matched result.

    – Sadegh

    Jan 23, 2015 at 12:02

  • 35

    also good to know, if you are just looking for a fixed string and not a regex, use -F option. it will save you scads of time by not invoking the regex parser. very handy if you are searching lots of files.

    – Jeff

    May 6, 2015 at 17:20

  • 7

    alias rgrep=’grep -r’

    – totten

    Mar 21, 2016 at 16:38


If you know the extension or pattern of the file you would like, another method is to use --include option:

grep -r --include "*.txt" texthere .

You can also mention files to exclude with --exclude.


If you frequently search through code, Ag (The Silver Searcher) is a much faster alternative to grep, that’s customized for searching code. For instance, it’s recursive by default and automatically ignores files and directories listed in .gitignore, so you don’t have to keep passing the same cumbersome exclude options to grep or find.


  • 3

    Works great with grep that comes with Linux & Cygwin, but not with the one that comes with AIX.

    – Withheld

    Jan 31, 2013 at 20:08

  • 1

    @KrzysztofWolny: ` ` instead of = works just fine on Ubuntu. PS: that’s supposed to be a backticked space, but the SO markdown parser failed.

    Feb 19, 2014 at 9:08

  • 6

    @DanDascalescu I upvoted for the grep, not for the Ag, just so you know 🙂

    – Bernhard

    May 15, 2014 at 7:24

  • 1

    Do we have an option to exclude a directory while searching recursively?

    Sep 24, 2017 at 15:47

  • Windows cygwin likes double-quotes --include "*.txt" --include "*.TXT"

    – Bob Stein

    Feb 19, 2019 at 16:48


I now always use (even on Windows with GoW — Gnu on Windows):

grep --include="*.xxx" -nRHI "my Text to grep" *

(As noted by kronen in the comments, you can add 2>/dev/null to void permission denied outputs)

That includes the following options:


Recurse in directories only searching file matching PATTERN.

-n, --line-number

Prefix each line of output with the line number within its input file.

(Note: phuclv adds in the comments that -n decreases performance a lot so, so you might want to skip that option)

-R, -r, --recursive

Read all files under each directory, recursively; this is equivalent to the -d recurse option.

-H, --with-filename

Print the filename for each match.


Process a binary file as if it did not contain matching data;
this is equivalent to the --binary-files=without-match option.

And I can add ‘i‘ (-nRHIi), if I want case-insensitive results.

I can get:

/home/vonc/gitpoc/passenger/gitlist/github #grep --include="*.php" -nRHI "hidden" *
src/GitList/Application.php:43:            'git.hidden'      => $config->get('git', 'hidden') ? $config->get('git', 'hidden') : array(),
src/GitList/Provider/GitServiceProvider.php:21:            $options['hidden'] = $app['git.hidden'];
tests/InterfaceTest.php:32:        $options['hidden'] = array(self::$tmpdir . '/hiddenrepo');
vendor/klaussilveira/gitter/lib/Gitter/Client.php:20:    protected $hidden;
vendor/klaussilveira/gitter/lib/Gitter/Client.php:170:     * Get hidden repository list
vendor/klaussilveira/gitter/lib/Gitter/Client.php:176:        return $this->hidden;


  • Gow looks promising – newer than the GNU Windows utilities that I have been using. Trying it now…

    Jan 23, 2016 at 0:16

  • 2

    what is the meaning of the last character * here?

    – lorniper

    Aug 4, 2016 at 7:07

  • 2

    @lorniper it makes the shell select all files and folders in your current directory, making in turn the grep apply to those files and (recursively because of the -R option) to the folders.

    – VonC

    Aug 4, 2016 at 7:10

  • 2

    @lorniper Noy exactly: * or . is a glob pattern (interpreted by the shell): ‘.‘ will select dotfiles or dot folders as well (like .git/)

    – VonC

    Aug 4, 2016 at 7:22

  • previously I’ve always used grep -rnI but then I learned that -n decreases performance a lot so I just use it when really needed and normally I’ll use -rI

    – phuclv

    Feb 3, 2019 at 3:33