I want to find all files which contain a specific string of text. The grep command works, but I don't know how to use it for every directory (I can only do it for my current directory). I tried reading man grep, but it didn't yield any help.
- 570
- 8,705
12 Answers
It would be better to use
grep -rl "string" /path
where
-r(or--recursive) option is used to traverse also all sub-directories of/path, whereas-l(or--files-with-matches) option is used to only print filenames of matching files, and not the matching lines (this could also improve the speed, given thatgrepstop reading a file at first match with this option).
- 96,093
If you're looking for lines matching in files, my favorite command is:
grep -Hrn 'search term' path/to/files
-Hcauses the filename to be printed (implied when multiple files are searched)-rdoes a recursive search-ncauses the line number to be printed
path/to/files can be . to search in the current directory
Further options that I find very useful:
-Iignore binary files (complement:-atreat all files as text)-Ftreatsearch termas a literal, not a regular expression-ido a case-insensitive search--color=alwaysto force colors even when piping throughless. To makelesssupport colors, you need to use the-roption:grep -Hrn search . | less -r--exclude-dir=diruseful for excluding directories like.svnand.git.

- 178,446
I believe you can use something like this:
find /path -type f -exec grep -l "string" {} \;
Explanation from comments
find is a command that lets you find files and other objects like directories and links in subdirectories of a given path. If you don't specify a mask that filesnames should meet, it enumerates all directory objects.
-type fspecifies that it should process only files, not directories etc.-exec grepspecifies that for every found file, it should run the grep command, passing its filename as an argument to it, by replacing{}with the filename
- 4,017
- 381
My default command is
grep -Rin string *
I use a capitol 'R' because ls uses it for recursive. Since grep accepts both, no reason to not use it.
EDIT: per HVNSweeting, apparently -R will follow symlinks where as -r will not.
- 1,802
If you’re willing to try something new, give ack a shot. The command to recursively search the current directory for string is:
ack string
Installation is quite simple:
curl http://betterthangrep.com/ack-standalone > ~/bin/ack && chmod 0755 !#:3
(Provided you’ve already got the directory ~/bin and it’s preferably in your PATH.)
- 427
grep (GNU or BSD)
You can use grep tool to search recursively the current folder with -r parameter, like:
grep -r "pattern" .
Note: -r - Recursively search subdirectories.
To search within specific files, you can use a globbing syntax such as:
grep "class foo" **/*.c
Note: By using globbing option (**), it scans all the files recursively with specific extension or pattern. To enable this syntax, run: shopt -s globstar. You may also use **/*.* for all files (excluding hidden and without extension) or any other pattern.
If you've the error that your argument is too long, consider narrowing down your search, or use find syntax instead such as:
find . -name "*.php" -execdir grep -nH --color=auto foo {} ';'
Alternatively use ripgrep.
ripgrep
If you're working on larger projects or big files, you should use ripgrep instead, like:
rg "pattern" .
Checkout the docs, installation steps or source code on the GitHub project page.
It's much quicker than any other tool like GNU/BSD grep, ucg, ag, sift, ack, pt or similar, since it is built on top of Rust's regex engine which uses finite automata, SIMD and aggressive literal optimizations to make searching very fast.
It supports ignore patterns specified in .gitignore files, so a single file path can be matched against multiple glob patterns simultaneously.
You can use the common parameters such as:
-i- Insensitive searching.-I- Ignore the binary files.-w- Search for the whole words (in opposite of partial word matching).-n- Show the line of your match.-C/--context(e.g.-C5) - Increases context, so you see the surrounding code .--color=auto- Mark up the matching text.-H- Displays filename where the text is found.-c- Displays count of matching lines. Can be combined with-H.
- 10,944
The command rgrep is dedicated for such need
If not available, you can get it like this
mkdir -p ~/bin
cd ~/bin
wget http://sdjf.esmartdesign.com/files/rgrep
chmod +x rgrep
You can directly set into your default grep options as described above.
I personnaly use
[[ ${#args} -lt 5 && "${args//[[:space:]]/}" == "-i" ]] && args="-Hin"
args="${args:--Hns} --color=auto"
related topic : how to always use rgrep with color
Update 2:
This line of commands using find and grep fixes the problem:
$ find path_to_search_in -type f -exec grep -in searchString {} 2> /dev/null +
--color=<always or auto> for colored output:
$ find path_to_search_in -type f \
-exec grep --color=always -in searchString {} 2>/dev/null +
Example:
$ find /tmp/test/ -type f -exec grep --color=auto -in "Search string" {} 2>/dev/null +
An example run in the snapshot below:

Update 1:
You can try following code; as a function in your .bashrc or .bash_aliases or in a script:
wherein () { for i in $(find "$1" -type f 2> /dev/null); do if grep --color=auto -i "$2" "$i" 2> /dev/null; then echo -e "\033[0;32mFound in: $i \033[0m\n"; fi; done }
Usage: wherein /path/to/search/in/ searchkeyword
example:
$ wherein ~/Documents/ "hello world"
(Note: As suggested in the comments below by @enzotib, this doesn't work with file/directories including spaces in their names.)
Original post
To search for the string and output just that line with the search string:
$ for i in $(find /path/of/target/directory -type f); do \
grep -i "the string to look for" "$i"; done
e.g.:
$ for i in $(find /usr/share/applications -type f); \
do grep -i "web browser" "$i"; done
To display filename containing the search string:
$ for i in $(find /path/of/target/directory -type f); do \
if grep -i "the string to look for" "$i" > /dev/null; then echo "$i"; fi; done;
e.g.:
$ for i in $(find /usr/share/applications -type f); \
do if grep -i "web browser" "$i" > /dev/null; then echo "$i"; \
fi; done;
- 16,917
I do this using xargs, a very underrated command
find ./ -type f -print0 | xargs -0 grep 'string_you_are_looking_for'
find ./ gives you a recursive list of all the files in a current folder then you pipe it to xargs that executes the grep command on each one of those files
- 36,350
- 121
There is a very fast alternative to grep called the Platinum Searcher. You can download it here.
- 376
I know there are plenty of answers here, but here's an alternative if you'd like to add other restrictions when searching the files:
find . -type f -exec grep --quiet string_to_look_for {} ';' -print
This works because grep will return 0 if it found a result, 1 otherwise. For example you can find files 1 MB large and containing something:
find . -type f -exec grep --quiet string_to_look_for {} ';' -size 1M -print
For multiple requirements you probably want to use the optimizer flag -O that exists in GNU grep.
- 153
A script (find-in-code) to search in C, CPP code:
#!/bin/sh
find . \( -iname "*.c" -o -iname "*.cpp" -o -iname "*.h" \) -type f -print0 | xargs -0 grep --color -n "$1"
Use:
find-in-code "search string"
- 1,250