How do I recursively grep all directories and subdirectories?

LinuxUnixGrep

Linux Problem Overview


How do I recursively grep all directories and subdirectories?

find . | xargs grep "texthere" *

Linux Solutions


Solution 1 - Linux

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.

Solution 2 - Linux

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.

Ag

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.

Solution 3 - Linux

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:

--include=PATTERN

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

-I     

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

Solution 4 - Linux

Also:

find ./ -type f -print0 | xargs -0 grep "foo"

but grep -r is a better answer.

Solution 5 - Linux

globbing **

Using grep -r works, but it may overkill, especially in large folders.

For more practical usage, here is the syntax which uses globbing syntax (**):

grep "texthere" **/*.txt

which greps only specific files with pattern selected pattern. It works for supported shells such as Bash +4 or zsh.

To activate this feature, run: shopt -s globstar.

See also: <https://stackoverflow.com/q/16956810/55075>

git grep

For projects under Git version control, use:

git grep "pattern"

which is much quicker.

ripgrep

For larger projects, the quickest grepping tool is ripgrep which greps files recursively by default:

rg "pattern" .

It's built on top of Rust's regex engine which uses finite automata, SIMD and aggressive literal optimizations to make searching very fast. Check the detailed analysis here.

Solution 6 - Linux

In POSIX systems, you don't find -r parameter for grep and your grep -rn "stuff" . won't run, but if you use find command it will:

find . -type f -exec grep -n "stuff" {} \; -print

Agreed by Solaris and HP-UX.

Solution 7 - Linux

If you only want to follow actual directories, and not symbolic links,

grep -r "thingToBeFound" directory

If you want to follow symbolic links as well as actual directories (be careful of infinite recursion),

grep -R "thing to be found" directory

Since you're trying to grep recursively, the following options may also be useful to you:

-H: outputs the filename with the line

-n: outputs the line number in the file

So if you want to find all files containing Darth Vader in the current directory or any subdirectories and capture the filename and line number, but do not want the recursion to follow symbolic links, the command would be

grep -rnH "Darth Vader" .

If you want to find all mentions of the word cat in the directory

/home/adam/Desktop/TomAndJerry 

and you're currently in the directory

/home/adam/Desktop/WorldDominationPlot

and you want to capture the filename but not the line number of any instance of the string "cats", and you want the recursion to follow symbolic links if it finds them, you could run either of the following

grep -RH "cats" ../TomAndJerry                   #relative directory

grep -RH "cats" /home/adam/Desktop/TomAndJerry   #absolute directory

Source:

running "grep --help"

A short introduction to symbolic links, for anyone reading this answer and confused by my reference to them: https://www.nixtutor.com/freebsd/understanding-symbolic-links/

Solution 8 - Linux

just the filenames can be useful too

grep -r -l "foo" .

Solution 9 - Linux

To find name of files with path recursively containing the particular string use below command for UNIX:

find . | xargs grep "searched-string"

for Linux:

grep -r "searched-string" .

find a file on UNIX server

find . -type f -name file_name

find a file on LINUX server

find . -name file_name

Solution 10 - Linux

ag is my favorite way to do this now github.com/ggreer/the_silver_searcher . It's basically the same thing as ack but with a few more optimizations.

Here's a short benchmark. I clear the cache before each test (cf https://askubuntu.com/questions/155768/how-do-i-clean-or-disable-the-memory-cache )

ryan@3G08$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time grep -r "hey ya" .

real	0m9.458s
user	0m0.368s
sys	0m3.788s
ryan@3G08:$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time ack-grep "hey ya" .

real	0m6.296s
user	0m0.716s
sys	0m1.056s
ryan@3G08$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time ag "hey ya" .

real	0m5.641s
user	0m0.356s
sys	0m3.444s
ryan@3G08$ time ag "hey ya" . #test without first clearing cache

real	0m0.154s
user	0m0.224s
sys	0m0.172s

Solution 11 - Linux

This should work:

grep -R "texthere" *

Solution 12 - Linux

If you are looking for a specific content in all files from a directory structure, you may use find since it is more clear what you are doing:

find -type f -exec grep -l "texthere" {} +

Note that -l (downcase of L) shows the name of the file that contains the text. Remove it if you instead want to print the match itself. Or use -H to get the file together with the match. All together, other alternatives are:

find -type f -exec grep -Hn "texthere" {} +

Where -n prints the line number.

Solution 13 - Linux

This is the one that worked for my case on my current machine (git bash on windows 7):

find ./ -type f -iname "*.cs" -print0 | xargs -0 grep "content pattern"

I always forget the -print0 and -0 for paths with spaces.

EDIT: My preferred tool is now instead ripgrep: https://github.com/BurntSushi/ripgrep/releases . It's really fast and has better defaults (like recursive by default). Same example as my original answer but using ripgrep: rg -g "*.cs" "content pattern"

Solution 14 - Linux

grep -r "texthere" . (notice period at the end)

(^credit: https://stackoverflow.com/a/1987928/1438029)


Clarification:

grep -r "texthere" / (recursively grep all directories and subdirectories)

grep -r "texthere" . (recursively grep these directories and subdirectories)

grep recursive

> grep [options] PATTERN [FILE...] > > [options] > > -R, -r, --recursive > > Read all files under each directory, recursively. > > This is equivalent to the -d recurse or --directories=recurse option. > > http://linuxcommand.org/man_pages/grep1.html

grep help

$ grep --help

$ grep --help |grep recursive
  -r, --recursive           like --directories=recurse
  -R, --dereference-recursive

Alternatives

ack (http://beyondgrep.com/)

ag (http://github.com/ggreer/the_silver_searcher)

Solution 15 - Linux

In 2018, you want to use ripgrep or the-silver-searcher because they are way faster than the alternatives.

Here is a directory with 336 first-level subdirectories:

% find . -maxdepth 1 -type d | wc -l
     336

% time rg -w aggs -g '*.py'
...
rg -w aggs -g '*.py'  1.24s user 2.23s system 283% cpu 1.222 total

% time ag -w aggs -G '.*py$'
...
ag -w aggs -G '.*py$'  2.71s user 1.55s system 116% cpu 3.651 total

% time find ./ -type f -name '*.py' | xargs grep -w aggs
...
find ./ -type f -name '*.py'  1.34s user 5.68s system 32% cpu 21.329 total
xargs grep -w aggs  6.65s user 0.49s system 32% cpu 22.164 total

On OSX, this installs ripgrep: brew install ripgrep. This installs silver-searcher: brew install the_silver_searcher.

Solution 16 - Linux

Throwing my two cents here. As others already mentioned grep -r doesn't work on every platform. This may sound silly but I always use git.

git grep "texthere"

Even if the directory is not staged, I just stage it and use git grep.

Solution 17 - Linux

another syntax to grep a string in all files on a Linux system recursively

grep -irn "string" /

displays massive result so u might need to filter the output by piping

Solution 18 - Linux

In my IBM AIX Server (OS version: AIX 5.2), use:

find ./ -type f -print -exec grep -n -i "stringYouWannaFind" {} \; 

this will print out path/file name and relative line number in the file like:

./inc/xxxx_x.h

2865: /** Description : stringYouWannaFind */

anyway,it works for me : )

Solution 19 - Linux

Below are the command for search a String recursively on Unix and Linux environment.

for UNIX command is:

find . -name "string to be searched" -exec grep "text" "{}" \;

for Linux command is:

grep -r "string to be searched" .

Solution 20 - Linux

I guess this is what you're trying to write

grep myText $(find .)

and this may be something else helpful if you want to find the files grep hit

grep myText $(find .) | cut -d : -f 1 | sort | uniq

Solution 21 - Linux

For a list of available flags:

grep --help 

Returns all matches for the regexp texthere in the current directory, with the corresponding line number:

grep -rn "texthere" .

Returns all matches for texthere, starting at the root directory, with the corresponding line number and ignoring case:

grep -rni "texthere" /

flags used here:

  • -r recursive
  • -n print line number with output
  • -i ignore case

Solution 22 - Linux

Note that find . -type f | xargs grep whatever sorts of solutions will run into "Argument list to long" errors when there are too many files matched by find.

The best bet is grep -r but if that isn't available, use find . -type f -exec grep -H whatever {} \; instead.

Solution 23 - Linux

Just for fun, a quick and dirty search of *.txt files if the @christangrant answer is too much to type :-)

grep -r texthere .|grep .txt

Solution 24 - Linux

Here's a recursive (tested lightly with bash and sh) function that traverses all subfolders of a given folder ($1) and using grep searches for given string ($3) in given files ($2):

$ cat script.sh
#!/bin/sh

cd "$1"

loop () {
    for i in *
    do
        if [ -d "$i" ]
        then
            # echo entering "$i"
            cd "$i"
            loop "$1" "$2"
        fi
    done

    if [ -f "$1" ]
    then
        grep -l "$2" "$PWD/$1"
    fi

    cd ..
}

loop "$2" "$3"

Running it and an example output:

$ sh script start_folder filename search_string
/home/james/start_folder/dir2/filename

Solution 25 - Linux

For .gz files, recursively scan all files and directories Change file type or put *

find . -name \*.gz -print0 | xargs -0 zgrep "STRING"

Solution 26 - Linux

The syntax is:
cd /path/to/dir
grep -r <"serch_word name"> .

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionwpiriView Question on Stackoverflow
Solution 1 - LinuxVinko VrsalovicView Answer on Stackoverflow
Solution 2 - LinuxchristangrantView Answer on Stackoverflow
Solution 3 - LinuxVonCView Answer on Stackoverflow
Solution 4 - LinuxKurtView Answer on Stackoverflow
Solution 5 - LinuxkenorbView Answer on Stackoverflow
Solution 6 - LinuxrookView Answer on Stackoverflow
Solution 7 - LinuxSarcasticSullyView Answer on Stackoverflow
Solution 8 - LinuxchimView Answer on Stackoverflow
Solution 9 - LinuxGirdhar Singh RathoreView Answer on Stackoverflow
Solution 10 - LinuxdranxoView Answer on Stackoverflow
Solution 11 - Linuxsumit kumarView Answer on Stackoverflow
Solution 12 - LinuxfedorquiView Answer on Stackoverflow
Solution 13 - LinuxarkodView Answer on Stackoverflow
Solution 14 - LinuxGeoffrey HaleView Answer on Stackoverflow
Solution 15 - LinuxhughdbrownView Answer on Stackoverflow
Solution 16 - LinuxZstackView Answer on Stackoverflow
Solution 17 - LinuxgeekView Answer on Stackoverflow
Solution 18 - Linuxuser3606336View Answer on Stackoverflow
Solution 19 - LinuxGirdhar Singh RathoreView Answer on Stackoverflow
Solution 20 - LinuxVictor FariaView Answer on Stackoverflow
Solution 21 - LinuxJSON C11View Answer on Stackoverflow
Solution 22 - Linuxm.thomeView Answer on Stackoverflow
Solution 23 - LinuxPJ BrunetView Answer on Stackoverflow
Solution 24 - LinuxJames BrownView Answer on Stackoverflow
Solution 25 - LinuxShreesh Mohan VermaView Answer on Stackoverflow
Solution 26 - LinuxPooView Answer on Stackoverflow