Как я могу "grep" рекурсивно фильтровать имена файлов, которые я хочу с подстановочными знаками?

53661
OMA

Когда я хочу выполнить рекурсивный поиск grep в текущем каталоге, я обычно делаю:

grep -ir "string" . 

Но эта команда выполняет поиск во всех видах файлов, включая двоичные файлы (изображения, аудио, видео и т. Д.), Что приводит к очень медленному процессу поиска.

Если я сделаю это, например, это не сработает:

grep -ir "string" *.php 

Это не работает, потому что в текущем каталоге нет файлов PHP, но внутри некоторых подкаталогов в текущем каталоге, а имена подкаталогов не заканчиваются на «.php», поэтому grep не заглядывает внутрь них.

Итак, как я могу сделать рекурсивный поиск из текущего каталога, но также указав подстановочные знаки имени файла? (т.е.: поиск только в файлах, которые заканчиваются определенным расширением)

33

3 ответа на вопрос

46
Dan D.

Use grep's --include option:

grep -ir "string" --include="*.php" . 
Хорошо, кажется, моя версия grep была старой, потому что у нее не было этой опции (не удивительно, почему я не мог понять, как это сделать!). Я получил сообщение: "grep: нераспознанная опция` --include = *. Php '". Но я только что обновился до нового и теперь он работает. Спасибо! OMA 10 лет назад 1
Мне пришлось заменить точку в конце и использовать: `grep -ir" string "--include =" *. Php "*` Stuart 9 лет назад 0
Я думал, что период был только конец линии! Я не использовал или не нужно. boardtc 6 лет назад 0
14
terdon

Если у вас есть версия, в grepкоторой отсутствует --includeопция, вы можете использовать следующее. Оба они были протестированы на структуре каталогов, как это:

$ tree . ├── a ├── b │   └── foo2.php ├── c │   └── d │   └── e │   └── f │   └── g │   └── h │   └── foo.php ├── foo1.php └── foo.php 

Где все .phpфайлы содержат строку string.

  1. использование find

    $ find . -name '*php' -exec grep -H string {} + ./b/foo2.php:string ./foo1.php:string ./c/d/e/f/g/h/foo.php:string 

    объяснение

    Это найдет все .phpфайлы и затем запустит grep -H stringкаждый из них. С find«S -execварианта, {}заменяются каждый из найденных файлов. -HГоворит grepпечатать имя файла, а также согласованную линию.

  2. Предполагая, что у вас достаточно новая версия bash, используйте globstar:

    $ shopt -s globstar $ grep -H string **/*php b/foo2.php:string c/d/e/f/g/h/foo.php:string foo1.php:string 

    объяснение

    Как объяснено в руководстве по bash :

    globstar

    Если установлено, шаблон '**', используемый в контексте расширения имени файла, будет соответствовать всем файлам и нулю или более каталогов и подкаталогов. Если за шаблоном следует символ «/», совпадут только каталоги и подкаталоги.

    Таким образом, запустив, shopt -s globstarвы активируете функцию и globstarопцию Bash, которая позволяет **/*phpразвернуть все .phpфайлы в текущем каталоге ( **соответствует 0 или более каталогам, так же **/*phpсоответствует ./foo.php), которые затем выбираются string.

-2
Dennis Nolan

использование */*.php

Это делает поиск grep одним уровнем подкаталога

Что-то пошло не так, как звездочки и точки исчезли. Dennis Nolan 8 лет назад 0
Вы можете использовать обратные метки для форматирования кода и избежать двусмысленности в использовании звездочек для акцентирования при форматировании уценки. PS Обратите внимание, что вопрос о «рекурсивном поиске» задается в последнем абзаце (но не мое отрицательное мнение) RedGrittyBrick 8 лет назад 0
Неверный ответ, потому что, как вы упоминаете, он полезен только для глубинных структур каталогов одного уровня, но, тем не менее, это полезно знать;). Мой голос за это. OMA 7 лет назад 0

Похожие вопросы