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


40

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

grep -ir "string" .

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

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

grep -ir "string" *.php

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

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

Ответы:


58

Используйте grep«S --includeвариант:

grep -ir "string" --include="*.php" .

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

Я должен был заменить период в конце и использовать:grep -ir "string" --include="*.php" *
Стюарт

Я думал, что период был только конец линии! Я не использовал или не нужно.
Boardtc

14

Если у вас есть версия, в 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

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

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


Что-то пошло не так, как звездочки и точки исчезли.
Деннис Нолан

Вы можете использовать обратные метки для форматирования кода и избежать неоднозначности использования звездочек для акцентирования при форматировании уценки. PS Обратите внимание, что вопрос о «рекурсивном поиске» задается в последнем абзаце (но не мое отрицательное мнение).
RedGrittyBrick

Неверный ответ, потому что, как вы упоминаете, он полезен только для глубинных структур каталогов одного уровня, но, тем не менее, это полезно знать;). Мой голос за это.
OMA
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.