|Grep recursion broken?|
-r -R --recursive do not function
For many years I have used grep like this:
grep -r string *.ext
to find "string" in any file with a ".ext" extension anywhere below the current directory. (Also allowed, according to 'man grep': -R and --recursive)
However these days grep refuses to dive into any subdirectory when a file extension with wildcard is used. It still recurses when this type of command is issued:
grep -r string *
But never when there is a file extension included.
Thoughts? (I expect a bunch of "You should use 'find...' responses, so fire away, but the REAL issue is why doesn't grep go recursive with the wildcard any more?)
That looks like what is supposed to happen.
The wildcards are expanded by the shell (usually bash), not by grep.
If you test using ls, you can see that *.ext gives a list of files ending in .ext in the current directory, none of which are themselves directories, so grep gets nothing to match recursively.
Bash does not do glob matching recursively. zsh does, if you use ** instead of *, but hardly anyone seems to use zsh. Have you changed shells at any point?
You can search for specific file extensions with grep by adding the --include parameter. For example:
grep -R --include=*.ext string .
This will only match files with the ext extension in the current directory or below.
Thank you for these replies.
I agree with both of you ... except my systems do not. I have been testing your suggestions and variations for about 45 minutes, now.
graeme_p: Yes, wildcards are expanded by the shell. Using different shells produces the same result. In the past, grep has searched recursively from the "current" directory using the exact syntax I posted. I hope to get it to do that, again. It's a real pain to have to go into each directory and look only for the files contained there.
grep -R --include=*.ext string
omits the target to scan, and so scans every file, and never seems to end. I need to limit the scanning to one particular type of file, from the "current" directory on down recursively. Here's from 'man grep':
grep [OPTIONS] PATTERN [FILE...]
What I have done (for, like, 20 years) uses the same:
grep [-R] pattern [*.txt]
This says, "look for the string 'pattern' in all files that have the '.txt' file extension", starting in the current directory and recursively searching through all of its subdirectories.
That's what I want to happen. But grep is not searching recursively regardless of which shell I use and regardless of the syntax (-r, -R, --recursive, --include=, etc.)
The issue exists in both of these environments:
GNU grep 2.6.3
Fedora 12 (fresh install)
GNU grep 2.5.1
Thanks again for any thoughts.
It is always in the details. The dot at the end of the command is needed. It points to the current directory where the recursive search should start.
grep -R --include=*.ext string .
Well, there ya go. Thanks, lammert. That does the trick. Should be in the man pages. But then again, the method I have used for so long should have continued to function, too, so I guess we can't get everything we want, huh?
I am curious about why my tried-and-trusted method began failing a couple of months ago. I guess that's one for the "will forever remain a mystery" pile. Just weird. I hate it when stuff like that happens. :)
@lammert, thanks for that. It just proved very useful. I needed to check some Python written using 2.6 that I subsequently needed to run on 2.5. It was very easy to use grep for things like searching files for "with" statements (which need an import in 2.5 but not in 2.6).