How can I use grep to search multiple unnested directories?

You can concatenate several paths for grep to look for:

grep -r "some string" /code/internal/dev/ /code/public/dev/ /code/tools/

If you want to make maximal use of wildcards (and the hierarchy you posted is complete), you can do

grep -r "some string" /code/{*/dev,tools}/*.cs

Explanation:

The first step done is expansion of the braced list. foo{bar,baz}qux expands to foobarqux foobazqux. That is, there's a separate word generated for each comma-separated item in the list, with the prefix and postfix part attached to each. You can see how that works by doing

echo A{1,2,3,4}B

which outputs

A1B A2B A3B A4B

Note that this also works with multiple braces, and also with empty arguments; for example

echo {,1,2}{0,1,2}:{2,3}

gives

0:2 0:3 1:2 1:3 2:2 2:3 10:2 10:3 11:2 11:3 12:2 12:3 20:2 20:3 21:2 21:3 22:2 22:3

So after brace expansion, your command looks like this:

grep -r "some string" /code/*/dev/*.cs /code/tools/*.cs

The next step is wildcard expansion. You already know that for the *.cs part, but it also works for intermediate directories; moreover, if a / follows, only directories are matched. Therefore given your hierarchy (and making up file names for the .cs files), you'll get the command:

grep -r "some string" /code/internal/dev/file1.cs /code/internal/dev/file2.cs /code/public/dev/file3.cs /code/tools/file4.cs /code/tools/file5.cs

Only after all this has happened, grep is called with this list of arguments (note that the same happens with your original commands; grep never gets to see the *; expanding that is completely done by bash before calling grep).

Tags:

Search

Grep