Як я можу рекурсивно фільтрувати ім'я файлів, які я хочу, за допомогою магістральних символів?


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 '". Але я просто перейшов на новий і тепер це працює. Дякую!
ОМА

Мені довелося замінити період наприкінці і використати: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{}-Hgrep

  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

Це робить греп-пошук одним рівнем підкаталогу


Щось пішло не так, як зірочки і крапки зникли.
Денніс Нолан

Ви можете використовувати зворотні посилання для форматування коду та уникнути неоднозначності щодо використання зірочок для наголосу у форматуванні розмітки. PS зауважте, що в останньому пункті питання "про рекурсивний пошук" задається питанням (однак, не моїм свідченням).
RedGrittyBrick

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