How to use "grep" command to find text including subdirectories
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.
Solution 1:
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).
Solution 2:
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
.
Solution 3:
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
Solution 4:
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.
Solution 5:
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
.)