Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

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.

share|improve this question
    
grep -RIn <yor pattern> * Will search from current directories down in all text files. Not sure how to do my search recursively in file patterns like *.C with only grep –  user311346 Aug 1 at 17:13

7 Answers 7

up vote 106 down vote accepted

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 that grep stop reading a file at first match with this option).
share|improve this answer
5  
Actually 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 1 '11 at 12:19
    
There is also the -i flag which ignores case. –  Marco Ceppi Aug 1 '11 at 13:15
    
I 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 without find. –  enzotib Aug 1 '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 8 '11 at 15:54
1  
@N.N.: done :-) –  enzotib Aug 8 '11 at 16:04

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 treat search term as a literal, not a regular expression
  • -i do a case-insensitive search
  • --color=always to force colors even when piping through less. To make less 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.

Example output

share|improve this answer
8  
-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 1 '11 at 12:31
    
I did not know that, it always worked like I expected. It's my default command when looking for files. –  Lekensteyn Aug 1 '11 at 12:34
    
Is there a way to only consider files with a, say, .a extention (and to combine this with -r)? –  user2413 Nov 4 '12 at 22:54
3  
@user2413 Try --include '*.*' –  Lekensteyn Nov 5 '12 at 15:24
    
@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 at 21:59

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 proceed only files, not directories etc.
  • -exec grep specifies that for every found file, it should run grep command, passing its filename as an argument to it, by replacing {} with the filename
share|improve this answer
    
Just for those who don't know, adding -name '*.py' restricts the matches to files ending in '.py'. –  Daniel F Mar 23 at 1:10
    
I like that this covers clients that don't have -R implemented in their grep command. –  Aviose Aug 11 at 20:29

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

share|improve this answer
2  
Or just apt-get install ack-grep (, and add alias ack=ack-grep to your .bashrc) –  markijbema Aug 1 '11 at 20:37
    
What do the last parameters to the chmod command do? Are they specific for chmod or are they bash related (the !#:3 part)? –  Elliott Darfink Jan 21 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 at 16:59

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.

share|improve this answer
1  
To 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, use shopt -u dotglob ("unset"). The changes are temporary though, it only applies to the current shell. –  Lekensteyn Aug 1 '11 at 19:09
    
I 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 1 '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 1 '11 at 19:44
    
shops -s dotglob;grep -Rin string *;shopt -u dotglob works. –  Lekensteyn Aug 1 '11 at 19:56
    
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 1 '11 at 20:13

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;
share|improve this answer

I do this using xargs, a very underrated command

find ./ | xargs 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

share|improve this answer
4  
Using xargs without -print0 option to find and -0 option to xargs is deprecated, it will fail on filenames containing spaces. –  enzotib Aug 1 '11 at 15:45

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.