Как я могу использовать grep для поиска в нескольких неопубликованных каталогах?

21

Может показаться, что я задаю то же самое, что и этот вопрос , но у меня другие требования. Это пример моей файловой системы:

  • /код/
    • внутренний /
      • DEV /
      • основной/
    • общественности /
      • DEV /
      • основной/
      • выпуск/
    • инструменты/

/code/internal/dev/, /code/public/dev/И /code/tools/содержать подкаталоги для нескольких проектов. Я работаю почти исключительно в ветвях разработки /code/internal/и /code/public/и часто хочу найти текстовую строку в этих каталогах вместе с /code/tools/(у которой нет ветвей). В этих случаях мне нужно выполнить три отдельные команды:

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

Я хотел бы знать, есть ли одна команда, чтобы сделать это. Если нет, то мне, скорее всего, нужно написать простой скрипт bash.

Дэвид Кеннеди
источник

Ответы:

38

Вы можете объединить несколько путей для поиска grep:

grep -r "some string" /code/internal/dev/ /code/public/dev/ /code/tools/
Артур Шимчак
источник
Это так очевидно. Почему я не подумал об этом ?!
Дэвид Кеннеди
На самом деле, это выдает ошибку, grep: /code/internal/dev/*.cs: No such file or directoryесли я не удалю *.csиз команды. Это моя вина, потому что я поставил *.csв своем вопросе изначально.
Дэвид Кеннеди
14

Если вы хотите максимально использовать подстановочные знаки (и иерархия, которую вы разместили, полна), вы можете сделать

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

Объяснение:

Первый шаг - расширение списка скобок. foo{bar,baz}quxрасширяется до foobarqux foobazqux. То есть для каждого элемента в списке, разделенного запятыми, создается отдельное слово, к которому прикрепляется префикс и часть постфикса. Вы можете увидеть, как это работает, выполнив

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

какие выводы

A1B A2B A3B A4B

Обратите внимание, что это также работает с несколькими скобками, а также с пустыми аргументами; например

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

дает

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

Итак, после расширения скобки ваша команда выглядит так:

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

Следующий шаг - расширение по шаблону. Вы уже знаете это для *.csчасти, но это также работает для промежуточных каталогов; Более того, если a /следует, только каталоги сопоставляются. Поэтому, учитывая вашу иерархию (и составляя имена файлов для .csфайлов), вы получите команду:

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

Только после того, как все это произошло, grepвызывается с этим списком аргументов (обратите внимание, что то же самое происходит с вашими исходными командами; grepникогда не открывается *; расширение, которое полностью выполняется bashперед вызовом grep).

celtschk
источник