2

Я хочу найти ключевое слово "test" во всех файлах типа "* .spec.in" в текущем каталоге. Это не работает:

grep -rn "test" ./*.spec.in

Как мне это сделать?

1 ответ1

2

Если вы думаете о том, что это делает, это не может работать. Флаг -r означает, что grep будет ожидать каталог как источник файла, но ваш глобус будет соответствовать файлам (или ничего). Это несоответствие.

Вы можете сделать это несколькими способами.

Способ "учебника", который можно использовать в любой UNIX (на самом деле, в любой оболочке), заключается в разделении ответственности. Используйте find чтобы выполнить рекурсию, и отдельно выполните grep. Давайте найдем все подходящие файлы и передадим их в grep

find . -type f -name '*.spec.in' | xargs grep -n "test"

найдите, начиная с этого момента, файлы с именем, совпадающим с '* .spec.in', передав этот поток в xargs, который превратит поток в аргументы командной строки для вашего grep.

Если у вас нет пробелов в именах файлов, это нормально. Но если вы это сделаете, или если вы используете это для внесения изменений на диске, вы, вероятно, захотите сделать это немного жестче. Есть хаки, в которых вы можете связываться с именами файлов, чтобы нанести вред важным файлам на диске, поэтому вы должны быть очень осторожны при взломе имен файлов. Для обеспечения безопасности или пробелов в именах вы можете указать find и xargs более плотно общаться. Смотрите -print0 , -0 ниже.

find . -type f -name '*.spec.in' -print0 | xargs  -0 something_destructive_like_rm

В новых оболочках, таких как zsh или в более новых версиях bash, вы можете использовать рекурсивные глобусы, которые используют специальный ** синтаксис. Они будут рекурсивно соответствовать шаблону файла.

shopt -s globstar # needed for bash, not for zsh
grep "test" ./**/*.spec.in

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .