[linux] How do I grep recursively?

How do I recursively grep all directories and subdirectories?

find . | xargs grep "texthere" *

This question is related to linux unix grep

The answer is


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

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/


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

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.


Also:

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

but grep -r is a better answer.


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

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

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

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.


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

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

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.


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.


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

just the filenames can be useful too

grep -r -l "foo" .

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

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


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.


This should work:

grep -R "texthere" *

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

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"


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

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: How do I find all files containing specific text on Linux?

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.


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

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)


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


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.


Examples related to linux

grep's at sign caught as whitespace How to prevent Google Colab from disconnecting? "E: Unable to locate package python-pip" on Ubuntu 18.04 How to upgrade Python version to 3.7? Install Qt on Ubuntu Get first line of a shell command's output Cannot connect to the Docker daemon at unix:/var/run/docker.sock. Is the docker daemon running? Run bash command on jenkins pipeline How to uninstall an older PHP version from centOS7 How to update-alternatives to Python 3 without breaking apt?

Examples related to unix

Docker CE on RHEL - Requires: container-selinux >= 2.9 What does `set -x` do? How to find files modified in last x minutes (find -mmin does not work as expected) sudo: npm: command not found How to sort a file in-place How to read a .properties file which contains keys that have a period character using Shell script gpg decryption fails with no secret key error Loop through a comma-separated shell variable Best way to find os name and version in Unix/Linux platform Resource u'tokenizers/punkt/english.pickle' not found

Examples related to grep

grep's at sign caught as whitespace cat, grep and cut - translated to python How to suppress binary file matching results in grep Linux find and grep command together Filtering JSON array using jQuery grep() Linux Script to check if process is running and act on the result grep without showing path/file:line How do you grep a file and get the next 5 lines How to grep, excluding some patterns? Fast way of finding lines in one file that are not in another?