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,365
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 thatgrep
stop reading a file at first match with this option).

- 93,831
-
14Actually if "string" is a text pattern to find, it's better to use that functionality, otherwise someone can face problems when the string contains dot or special character which has meaning in regular expressions and not just a dot which should be found as a string, as-is. Then I would use
-rlF
switches,-F
for "fixed string" (and not regexp - for example). Of course, if the task was using regexps, then excuse me. Sure, the same theory without -r too, I often see that people assumes grep searches "text" and it can cause problems which special ones which mean something as a regexp. – LGB Aug 01 '11 at 12:19 -
5
-
3I would only to show the
--recursive
option, there are ton of options and usage scenarios one can talk about. I started from the @dmityugov accepted answer and modified to work withoutfind
. – enzotib Aug 01 '11 at 13:42 -
I would appreciate if you include the meaning of the command in your answer, e.g. the meaning of the options
-rl
. – N.N. Aug 08 '11 at 15:54 -
1
-
It would be really helpful if you also either mentioned @LGB's comment that your string is not a plain string, but rather a regexp, and about the
F
"fixed string" option. – Gerrat Oct 28 '14 at 13:28 -
How do you specify only certain types of files, like header (*.h) files? – SMBiggs Jun 18 '16 at 21:05
-
3
-
This is the first grep command I've ever seen that actually makes sense. Not to hate on the all powerful grep. Long live grep. – legel Dec 09 '20 at 10:41
If you're looking for lines matching in files, my favorite command is:
grep -Hrn 'search term' path/to/files
-H
causes the filename to be printed (implied when multiple files are searched)-r
does a recursive search-n
causes the line number to be printed
path/to/files
can be .
to search in the current directory
Further options that I find very useful:
-I
ignore binary files (complement:-a
treat all files as text)-F
treatsearch term
as a literal, not a regular expression-i
do a case-insensitive search--color=always
to force colors even when piping throughless
. To makeless
support colors, you need to use the-r
option:grep -Hrn search . | less -r
--exclude-dir=dir
useful for excluding directories like.svn
and.git
.

- 174,277
-
13
-H
on a folder is redundant, if there is more then one file, as is probable. In fact, the man page says-H, --with-filename: Print the file name for each match. This is the default when there is more than one file to search.
– enzotib Aug 01 '11 at 12:31 -
1I did not know that, it always worked like I expected. It's my default command when looking for files. – Lekensteyn Aug 01 '11 at 12:34
-
1Is there a way to only consider files with a, say, .a extention (and to combine this with -r)? – user2413 Nov 04 '12 at 22:54
-
6
-
@enzotib Just a FYI: I don't get the nice clean output of every line in every file where my text appears with -rln nor -rl, but I do with -Hrn. Redundant or not, it looks like the screenshot above with the -Hrn options. Also, it doesn't seem like -n works without -H. – SgtPooki Mar 25 '14 at 21:59
-
@SgtPooki the
-l
option prints just the file name, not the line (number) themselves. – Lekensteyn Mar 25 '14 at 23:36 -
-
@SgtPooki On my system (
grep
version 2.18),grep -n key file
shows line numbers before each line (without file name).grep -nH key file
prints the filename, line number and line.grep -rn key .
prints the filename, line number and line for every file recursively. – Lekensteyn Mar 26 '14 at 09:33 -
@Lekensteyn you're right. the -l option breaks the -n option. (GNU grep 2.6.3) – SgtPooki Mar 26 '14 at 14:21
-
-
1
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 f
specifies that it should process only files, not directories etc.-exec grep
specifies 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,007

- 371
-
3Just for those who don't know, adding
-name '*.py'
restricts the matches to files ending in '.py'. – Daniel F Mar 23 '14 at 01:10 -
I like that this covers clients that don't have -R implemented in their grep command. – Aviose Aug 11 '14 at 20:29
-
If you want the matching line AND filename printed, make exec like:
... -exec bash -c 'grep -r "mystring" {} && echo {}' \;
– Donn Lee May 06 '19 at 23:24 -
-
-
2
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
-
1To search in hidden files too, run
shopt -s dotglob
(remember-s
as "set"). Be careful when removing files then. If you've dotglob enabled,rm -r *
removes everything in the current dir, but also the directory above it because..
matches. To disable dotglob, useshopt -u dotglob
("unset"). The changes are temporary though, it only applies to the current shell. – Lekensteyn Aug 01 '11 at 19:09 -
1I forgot about this. Is there a way to set it for one the one line? something like
shopt -s dotglob & <grep cmd> & shopt -y dotglob
only more convenient? This way we won't have to worry about resetting it – user606723 Aug 01 '11 at 19:42 -
Also, it's probably easier to use
grep -Rin string .
in most of these cases. I just use * because it seems to come more naturally. – user606723 Aug 01 '11 at 19:44 -
-
yeah... but.. it'd be nice if there was a command that only worked for the single line. instead of turning it on and off in the same line, whjich is silly – user606723 Aug 01 '11 at 20:13
-
bash -c 'shopt -s dotglob;grep -Rin string *'
, but now it gets dirty. Just usegrep -Rin string .
– Lekensteyn Aug 01 '11 at 21:11 -
1if you do recursive grep, then you can just start from "." instead of "*". no dotglob needed. – Michał Šrajer Aug 07 '11 at 16:32
-
1vote up this, one thing doesn't mention in manpage is
R
will follow symbolic links,r
does not – HVNSweeting Jan 25 '13 at 04:06
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
-
2Or just apt-get install ack-grep (, and add alias ack=ack-grep to your .bashrc) – markijbema Aug 01 '11 at 20:37
-
What do the last parameters to the
chmod
command do? Are they specific forchmod
or are they bash related (the!#:3
part)? – Elliott Darfink Jan 21 '14 at 10:06 -
@ElliottDarfink That’s using Bash’s history feature –
!
is an event designator. They’re pretty powerful to avoid repetitions.!#:3
references the third token of the command line so far, i.e.~/bin/ack
in this case. – Konrad Rudolph Jan 21 '14 at 16:59
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,347
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
-
rgrep is provided by the grep package which is installed by default in Ubuntu. – karel Jan 02 '15 at 14:16
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,327
-
Fails on filenames containing spaces. The failing is hided by the fact that stderr is not shown. – enzotib Jan 13 '15 at 09:38
-
@enzotib thanks for pointing that out.. that's still unresolved for the function specified.. I've added another one-liner though.. – rusty Jan 13 '15 at 20:38
-
-
yes, but in that sense most of the answers in this page if you check are similar in respect that they use
grep
, next to that being the subset usingfind
withgrep
... but if you are to accept different switches and tweaks as a distinct answer, probably mine will fit in here too.. or do you differ? the last update does what I'd like in my search: file names with lines with search key and line no. too :) and colored output and error filter for better readability.. – rusty Jan 14 '15 at 06:44
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

- 35,660

- 121
-
4Using
xargs
without-print0
option tofind
and-0
option toxargs
is deprecated, it will fail on filenames containing spaces. – enzotib Aug 01 '11 at 15:45 -
@enzotib I have edited the answer as you suggested.- please review and if needs to editing and correcting, I will happy re-editing by you. thank you – αғsнιη Jan 13 '15 at 09:00
-
1
There is a very fast alternative to grep called the Platinum Searcher. You can download it here.

- 346
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
- 8
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,160
- 9
- 7
--include="*.C"
option, @user311346, thanks to @Lekensteyn. – Bob Stein Feb 06 '15 at 20:36