10

In Windows, if I wanted to find a string across all files in all subdirectories, I would do something like

findstr /C:"the string" /S *.h

However, in Linux (say, Ubuntu) I have found no other way than some piped command involving find, xargs, and grep (an example is at this page: How can I recursively grep through sub-directories?). However, my question is different: is there any single, built-in command that works through this magic, without having to write my shell script?

17

GNU grep allows searching recursively through subdirectories:

grep -r --include='*.h' 'the string' .
  • I tried this exact command line in Ubuntu but get "grep: invalid option -- 'M'" although I can't see any 'M' anywhere... puzzling – Guido Domenici Feb 14 '11 at 14:45
  • @Guido Works fine over here – phunehehe Feb 14 '11 at 15:15
  • In a suggested edit TomasG recommends changing the last * to '*': "Quoting the last wildcard is needed to avoid errors when some filename starts with -" – Michael Mrozek Feb 14 '11 at 16:07
  • In a strange twist of events, it now works for me too, as entered in the original answer. Thanks! – Guido Domenici Feb 14 '11 at 16:34
  • 1
    @Guido: Your problem may have been due to a file in the current directory called -Msomething, or to a GREP_OPTIONS setting. – Gilles Feb 14 '11 at 20:43
2

grep -r searchpattern /path/to/start/in

Where /path/to/start/in/ can be just "." for the current directory.

1

No. find -name \*.h -print0 | xargs -0 grep -l 'the regex' is as magic as it gets.

  • GNU grep has the common cases built-in with its -r option. No need for the heavy artillery. – Gilles Feb 14 '11 at 20:44
  • 2
    xargs adds just noise. Use find -name \*.h -execdir grep -l 'the regex {} + – user unknown Apr 15 '11 at 22:47
0

is there any single, built-in command that works through this magic ... ?

To be pedantic, no, you cannot assume such a command exists.

There are many different implementations of Unix, and each has its different quirks. POSIX, the common denominator (and closest thing to a standard across Unices) does not specify such an option for grep.

As mentionned in other answers, GNU's implementation of grep has a non-standard option that does what you want. While this particular implementation might be common on Linux systems, you cannot assume its availability on any Unix, even some Linux systems.

Finally, I should mention that it is the Unix philosophy to favor the combination of several primitive programs, over the use of one big monolithic executable attempting to do everything at once.

In your case, crawling the file system and matching regexp in a stream are two separate tasks. It is only normal to treat each in a separate program.

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.