8

Whenever I use grep with gnuwin32's recurse option -r and include a glob pattern for files to search (e.g. *.c), no files in the subdirectories are searched. I am using the latest grep from gnuwin32.

Specifically, I was searching for the string "iflag" in all my c source files in a directory.

grep -r iflag *.c
4
  • Can you give the exact command you are trying to execute? Oct 28, 2013 at 21:39
  • I've updated at your request. Oct 28, 2013 at 21:42
  • Possibly related: -r and file globs don't do what you want usually. Oct 29, 2013 at 18:47
  • If you ask me, if the wildcard isn't supported for recursion, we should at least get an error or warning. Maybe it's too late to add a feature like this to such an old, important application, but a warning would be good. I think the "rpl" command has the same problem, it can't handle *.whatever recursively.
    – PJ Brunet
    Feb 23, 2017 at 18:16

3 Answers 3

6

Grep's -r option (which is the same as the -R, --recursive, -d recurse and --directories=recurse options) takes a directory name (or pattern) as its argument. The command you are trying to execute should be interpreted as "Starting in the current working directory recurse all directories matching the pattern *.c. In each of those directories search all files for the string iflag."

5
  • If you make "takes a directory name (or pattern) as its argument" bold I'll make your answer the accepted answer. I thought the -r option searched through the current working directory automatically. Thanks! Oct 29, 2013 at 18:28
  • I tried -r and -R and --directories=recurse, neither found matches in a subdirectory. Please add an example, because grep -r "whatever" *.php does not work grep -r . "whatever" *.php does not work. I always assumed a mature application like grep would not have such a fatal flaw, I've been using it for over a decade, how did I miss this? It was just luck that I was in a subdirectory and found matches that were not found via the parent directory. Oddly, the "--include" solution works perfectly. I'm using CentOS 6.
    – PJ Brunet
    Feb 23, 2017 at 16:17
  • If you can show a working example, I'll retract my downvote. But this does not work. Sorry. The other answer works. If you told me this works, I would take your word for it, because it's grep. And yet, it doesn't work. Strange.
    – PJ Brunet
    Feb 23, 2017 at 16:22
  • 4
    @PJBrunet your issue is basically the same as the OP. Grep doesn't work the way you (and I) think it should. if you want to recursively search the current directory for the string "whatever" but only in files matching the pattern "*.php" then your command would be grep -r whatever . --include *.php Mar 1, 2017 at 3:05
  • Good thing I found this answer. The grep v3.1 I am using via git-bash on windows does not indicate that it requires a directory name as an argument. "-r, --recursive like --directories=recurse"
    – shawn1874
    Apr 30, 2021 at 15:39
7

I'm not sure why the recurse flag doesn't work, but here's a workaround that works for me. The -r option takes an argument: the directory to search. To search the current directory, give it the argument .. For example

grep regexp-to-find -r . --include=*.c

Edit

This is actually the expected behavior of grep, and has nothing to do with running it on Windows. The -r option takes a directory argument. Check out HairOfTheDog's answer for why.

2
  • If anyone else has a better answer (this does not include suggesting just switching to cygwin, heh) I'll gladly accept it. Oct 28, 2013 at 21:27
  • However, nobody ever explained why the '-r' option needs to be after the pattern which seems contrary to the grep documentation.
    – shawn1874
    Apr 30, 2021 at 15:51
1

I find the answers given so far way too complicated. Just use:

grep -r --include="*.c" searchString .

(as proposed by christangrant on StackOverflow or by HairOfTheDog in the comments above.)

If you are too lazy to type that all the time, just define a function and add it to "~/.bashrc". (A normal alias is not possible since parameters are used, as explained on StackOverflow)

rgrep() {
  grep -r --include="$2" "$1" .
}

Now you have an easy to use recursive grep. E.g., if you want to search for "string" in all text files, use:

rgrep string "*.txt"
1
  • I don't really like that one has to add quotes around the file type. If it is possible without, and anybody knows how to alter the function, please do so!
    – Prof.Chaos
    Feb 6, 2021 at 2:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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