11

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?

5 Answers5

24

GNU grep allows searching recursively through subdirectories:

grep -r --include='*.h' 'the string' .
wag
  • 35,944
  • 12
  • 67
  • 51
2

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

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

mattdm
  • 40,245
1

To find string from given directory use below command

find <fullDirectoryPath> -name '*' -exec grep -l '<StringToFind>' {} \;

For example:

find /apps_bev/apps/xfer/export/02210 -name '*' -exec grep -l '38221000001032' {} \;
Yogesh
  • 111
  • 2
  • 1
    grep can take more than one file as arguments, so you should use + instead of \; to avoid running one grep invocation per file which is quite inefficient. – Stéphane Chazelas Nov 20 '19 at 07:39
  • 1
    Note that -name '*' restricts to files whose name is valid text in the current locale (in some find implementations at least), but the other directory components may still contain sequences of bytes that don't form valid characters. If your intention with that -name '*' was to make sure the output is valid text (by omiting the files with improper names), you'd rather use find ... ! -name '*' -prune -o -exec grep ... {} +, which would also stop find from descending into directories with improper names. – Stéphane Chazelas Nov 20 '19 at 07:44
1

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

glenn jackman
  • 85,964
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.

rahmu
  • 20,023