Вы также можете использовать Globstar.
Создание grepкоманд с помощью find, как в ответе Занны , является очень надежным, универсальным и переносимым способом сделать это (см. Также ответ Судодуса ). И Муру опубликовали отличный подход использования grep«s --includeварианта . Но если вы хотите использовать только grepкоманду и вашу оболочку, есть другой способ сделать это - вы можете заставить саму оболочку выполнить необходимую рекурсию :
shopt -s globstar # you can skip this if you already have globstar turned on
grep -H 'pattern' **/file.txt
В -Hфлаг марки grepпоказать имя файла , даже если только один соответствующий файл найден. Вы можете передать -a, -iи -nфлаги (из вашего примера), grepа также, если это то, что вам нужно. Но не пропустите -rили -Rпри использовании этого метода. Это оболочка, которая рекурсивно использует каталоги в расширении шаблона glob, содержащего **, а неgrep .
Эти инструкции относятся к оболочке Bash. Bash - это пользовательская оболочка по умолчанию в Ubuntu (и в большинстве других операционных систем GNU / Linux), поэтому, если вы используете Ubuntu и не знаете, какая у вас оболочка, это почти наверняка Bash. Несмотря на то, что популярные оболочки обычно поддерживают **глобальные списки, они не всегда работают одинаково. Для получения дополнительной информации см Stéphane Chazelas «s отличный ответ на Результат логинсервера *, ** Ls и Ls *** на Unix.SE .
Как это устроено
Включение опции оболочки globstar bash позволяет **сопоставлять пути, содержащие разделитель каталогов ( /). Таким образом, это рекурсивный глобус каталога. В частности, как man bashобъясняет:
Когда опция оболочки globstar включена и * используется в контексте расширения имени пути, два смежных *, используемых в качестве единого шаблона, будут соответствовать всем файлам и нулю или более каталогов и подкаталогов. Если после / / два соседних * будут соответствовать только каталогам и подкаталогам.
Вы должны быть осторожны с этим, так как вы можете запускать команды, которые изменяют или удаляют гораздо больше файлов, чем вы предполагаете, особенно если вы пишете, **когда намеревались писать *. (Это безопасно в этой команде, которая не меняет никаких файлов.) shopt -u globstarОтключает опцию оболочки globstar.
Есть несколько практических различий между Globstar и find.
findгораздо более универсален, чем Globstar. Все, что вы можете сделать с globstar, вы можете сделать и с findкомандой. Мне нравится globstar, и иногда это удобнее, но globstar не является общей альтернативой find.
Метод выше не ищет внутри каталогов, имена которых начинаются с .. Иногда вы не хотите использовать такие папки, но иногда это так.
Как и в случае с обычным глобаном, оболочка создает список всех подходящих путей и передает их в качестве аргументов вашей команде ( grep) вместо самого глобуса. Если вы называете так много файлов, file.txtчто полученная команда будет слишком длинной для выполнения системой, то приведенный выше метод завершится ошибкой. На практике вам понадобится (как минимум) тысячи таких файлов, но это может произойти.
Используемые методы findне подпадают под это ограничение, потому что:
Путь Занны строит и запускает grepкоманду с потенциально большим количеством аргументов пути. Но если найдено больше файлов, чем может быть указано в одном пути, действие +-terminated -execзапускает команду с некоторыми из путей, затем запускает ее снова с еще несколькими путями и так далее. В случае использования grepдля строки в нескольких файлах это приводит к правильному поведению.
Как и описанный здесь метод globstar, он печатает все совпадающие строки с путями, добавленными к каждой.
Путь Судодуса проходит grepотдельно для каждого file.txtнайденного. Если есть много файлов, это может быть медленнее, чем некоторые другие методы, но это работает.
Этот метод находит файлы и печатает их пути, после чего следуют соответствующие строки, если таковые имеются. Это формат вывода, отличный от формата, созданного моими методами, Zanna и Muru .
Получение цвета с find
Одним из непосредственных преимуществ использования globstar является то, что по умолчанию в Ubuntu grepбудет производить цветной вывод. Но вы можете легко получить это findтоже .
Учетные записи пользователей в Ubuntu создаются с псевдонимом, который grepдействительно запускает grep --color=auto(бегите, alias grepчтобы увидеть). Это хорошая вещь , что псевдонимы в значительной степени только расширяется , когда вы выдаете их в интерактивном режиме , но это означает , что если вы хотите , findчтобы вызвать grepс --colorфлагом, вы должны написать его в явном виде. Например:
find . -name file.txt -exec grep --color=auto -H 'pattern' {} +