Bagaimana saya bisa "grep" secara memfilter menyaring nama file yang saya inginkan dengan wildcard?

40

Ketika saya ingin melakukan pencarian grep rekursif di direktori saat ini, saya biasanya melakukan:

grep -ir "string" .

Tapi perintah itu mencari di dalam semua jenis file, termasuk file biner (gambar, audio, video, dll ...) yang menghasilkan proses pencarian yang sangat lambat.

Jika saya melakukan ini, misalnya, itu tidak berfungsi:

grep -ir "string" *.php

Itu tidak berfungsi karena tidak ada file PHP di dalam direktori saat ini, tetapi di dalam beberapa subdirektori di direktori saat ini, dan nama-nama subdirektori tidak diakhiri dengan ".php" sehingga grep tidak melihat di dalamnya.

Jadi, bagaimana saya bisa melakukan pencarian rekursif dari direktori saat ini tetapi juga menentukan wildcard nama file? (yaitu: hanya mencari di file yang berakhir dengan ekstensi tertentu)

OMA
sumber

Jawaban:

58

Gunakan grep's --includepilihan:

grep -ir "string" --include="*.php" .
Dan D.
sumber
1
Ok, sepertinya versi grep saya sudah tua, karena tidak memiliki opsi itu (tidak heran mengapa saya tidak tahu bagaimana melakukan ini!). Saya mendapat pesan: "grep: opsi yang tidak dikenal` --include = *. Php '". Tapi saya baru saja meningkatkan ke yang lebih baru dan sekarang berfungsi. Terima kasih!
OMA
Saya harus mengganti periode di akhir dan menggunakan:grep -ir "string" --include="*.php" *
Stuart
Saya pikir periode hanyalah akhir dari garis! Saya tidak menggunakan atau membutuhkan.
boardtc
14

Jika Anda memiliki versi grepyang tidak memiliki --includeopsi, Anda dapat menggunakan yang berikut ini. Keduanya diuji pada struktur direktori seperti ini:

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

Di mana semua .phpfile berisi string string.

  1. Menggunakan find

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

    Penjelasan

    Ini akan menemukan semua .phpfile dan kemudian menjalankannya grep -H stringmasing-masing. Dengan find's -execpilihan, {}digantikan oleh masing-masing file yang ditemukan. The -Hmemberitahu grepuntuk mencetak nama file serta baris yang cocok.

  2. Dengan asumsi Anda memiliki versi yang cukup baru bash, gunakan globstar:

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

    Penjelasan

    Seperti yang dijelaskan dalam manual bash :

    globstar

    Jika diatur, pola '**' yang digunakan dalam konteks ekspansi nama file akan cocok dengan semua file dan nol atau lebih direktori dan subdirektori. Jika polanya diikuti oleh '/', hanya direktori dan subdirektori yang cocok.

    Jadi, dengan menjalankan shopt -s globstarAnda mengaktifkan fitur dan globstaropsi Bash yang membuat **/*phpperluas ke semua .phpfile di direktori saat ini ( **cocok dengan 0 atau lebih direktori, jadi **/*phpcocok ./foo.phpjuga) yang kemudian diterima string.

terdon
sumber
-2

Menggunakan */*.php

Ini membuat pencarian grep menjadi satu tingkat subdirektori

Dennis Nolan
sumber
Terjadi kesalahan saat tanda bintang dan titik menghilang.
Dennis Nolan
Anda dapat menggunakan backticks untuk memformat kode dan menghindari ambiguitas tentang penggunaan tanda bintang untuk penekanan dalam format markdown. PS perhatikan pertanyaan yang diajukan tentang "pencarian rekursif" di paragraf terakhir (bukan downvote saya).
RedGrittyBrick
Bukan jawaban yang benar, karena itu hanya baik untuk struktur direktori sedalam satu level, seperti yang Anda sebutkan, tetapi masih bagus untuk diketahui;). Suara positif saya untuk itu.
OMA