Ketika saya ingin grep semua file html di beberapa direktori, saya melakukan hal berikut
grep --include="*.html" pattern -R /some/path
yang bekerja dengan baik. Masalahnya adalah bagaimana cara grep semua file html, htm, php di beberapa direktori?
Dari Gunakan grep --exclude / - include syntax agar tidak grep melalui file tertentu , sepertinya saya bisa melakukan hal berikut
grep --include="*.{html,php,htm}" pattern -R /some/path
Tapi sayangnya, itu tidak akan berhasil untuk saya.
FYI, versi grep saya adalah 2.5.1.
xargs
. Ini juga layak untuk dibaca dengan cepat. HTH.*
masih tunduk pada globbing sebagai bagian dari token yang disematkannya , kebetulan tidak cocok dengan apa pun dalam kasus ini, karena hanya file yang secara harfiah bernama sesuatu yang--include=foo.html
cocok. Untuk amannya, kutip*
(yang dapat Anda lakukan secara individu\*
). Sebagai bonus tambahan, ini membuatnya lebih jelas secara visual bahwa bukan shell yang harus melakukan globbing dalam kasus ini.find
solusinya: menggunakan-exec grep "pattern" {} +
daripada| xargs grep "pattern"
lebih kuat (menangani nama file dengan spasi, misalnya) serta lebih efisien.Menggunakan
{html,php,htm}
hanya bisa bekerja sebagai ekspansi penjepit , yang merupakan tidak standar fitur (tidak POSIX-compliant) daribash
,ksh
, danzsh
.Dengan kata lain: jangan mencoba menggunakannya dalam skrip yang menargetkan
/bin/sh
- gunakan beberapa argumen eksplisit--include
dalam kasus itu.grep
sendiri tidak mengerti{...}
notasi.Agar perluasan tanda kurung kurawal dapat dikenali, itu harus berupa tanda kutip (bagian dari a) pada baris perintah.
Ekspansi brace meluas ke beberapa argumen , jadi dalam kasus yang dihadapi
grep
akhirnya melihat beberapa--include=...
opsi, seperti jika Anda meneruskannya satu per satu.Hasil ekspansi brace tunduk pada globbing (perluasan nama file) , yang memiliki kendala :
Setiap argumen yang dihasilkan selanjutnya dapat diperluas ke nama file yang cocok jika kebetulan berisi karakter meta globbing tanpa tanda kutip seperti
*
.Meskipun hal ini tidak mungkin terjadi dengan token seperti
--include=*.html
(mis., Anda harus memiliki file yang secara harfiah dinamai sesuatu yang--include=foo.html
cocok), perlu diingat secara umum.Jika
nullglob
opsi shell kebetulan dihidupkan (shopt -s nullglob
) dan globbing tidak cocok dengan apa pun , argumen akan dibuang .Oleh karena itu, untuk solusi yang sepenuhnya kuat , gunakan yang berikut ini:
'--include=*.'
diperlakukan sebagai literal , karena dikutip tunggal ; ini mencegah interpretasi yang tidak disengaja*
sebagai karakter yang menggelembung.{html,php,htm}
, the - of needs - unquoted brace expansion [1] , meluas menjadi 3 argumen, yang, karena{...}
mengikuti'...'
token secara langsung , termasuk token tersebut.Oleh karena itu, setelah penghapusan kutipan oleh shell, berikut 3 literal argumen akhirnya dilewatkan ke
grep
:--include=*.html
--include=*.php
--include=*.htm
[1] Lebih tepatnya, hanya bagian yang relevan dengan sintaks dari perluasan tanda kutip yang harus tidak diberi tanda kutip , elemen daftar mungkin masih dikutip secara individual dan harus berisi karakter meta penggabungan yang dapat mengakibatkan penggumpalan yang tidak diinginkan setelah perluasan tanda kurung; sementara tidak diperlukan dalam kasus ini, di atas dapat ditulis sebagai
'--include=*.'{'html','php','htm'}
sumber
bash
platform apa pun yangbash
berjalan.Coba hapus tanda kutip ganda
sumber
grep --include=\*.{html,php,htm} pattern -R /some/path
. Itu berhasil untuk saya.apakah ini tidak bekerja?
sumber
Coba ini. -r akan melakukan pencarian rekursif. -s akan menyembunyikan kesalahan file tidak ditemukan. -n akan menunjukkan nomor baris file tempat pola ditemukan.
sumber
-I
ke set standar. Ini melewatkan file biner (yang hampir tidak pernah dicari) sehingga meningkatkan efisiensi. Lalu kita pergigrep -rIns ...
yang memainkan akustik dengan baik :)Ia bekerja untuk tujuan yang sama, tetapi tanpa
--include
pilihan. Ia bekerja pada grep 2.5.1 juga.sumber
Gunakan
grep
denganfind
perintahAnda dapat menggunakan
-regex
dan-regextype
opsi juga.sumber