Salah satu perintah BASH favorit saya adalah:
find . -name '*.*' -exec grep 'SearchString' {} /dev/null \;
yang mencari konten semua file di dan di bawah direktori saat ini untuk SearchString yang ditentukan. Sebagai seorang pengembang, ini kadang-kadang berguna.
Karena proyek saya saat ini, dan struktur basis kode saya, saya ingin membuat perintah BASH ini lebih maju dengan tidak mencari file apa pun yang ada di atau di bawah direktori yang berisi ".svn", atau file apa pun yang akhiri dengan ".html"
Halaman MAN untuk menemukan agak membingungkan saya. Saya mencoba menggunakan -prune, dan itu memberi saya perilaku aneh. Dalam upaya untuk melewati hanya halaman .html (untuk memulai), saya mencoba:
find . -wholename './*.html' -prune -exec grep 'SearchString' {} /dev/null \;
dan tidak mendapatkan perilaku yang saya harapkan. Saya pikir saya mungkin kehilangan titik-proune. Bisakah kalian membantu saya?
Terima kasih
find
bukan perintah built-in bash tetapi program terpisahgrep -rl 'SearchString'
find
untuk mencari di dalam file.-name '*.*'
tidak menemukan semua file: hanya yang dengan.
nama mereka (penggunaan*.*
biasanya adalah DOS-isme, sedangkan di Unix, Anda biasanya menggunakan hanya*
untuk itu). Untuk benar-benar cocok dengan mereka semua, hanya menghapus argumen sama sekali:find . -exec ...
. Atau jika Anda hanya ingin menerapkan grep ke file (dan lewati direktori) maka lakukanfind . -type f -exec ...
.Jawaban:
Anda dapat menggunakan fitur negate (!) Find untuk tidak mencocokkan file dengan nama tertentu:
Jadi jika nama berakhir dengan .html atau mengandung .svn di mana saja di jalan, itu tidak akan cocok, dan karenanya eksekutif tidak akan dieksekusi.
sumber
*.*
kecocokan Anda untuk memastikan hanya kecocokan file yang mengandung.
? Temukan akan cocok dengan semua file dengan tidak adanyaname
arahan, sehingga di atas akan cocok dengan semuanya kecuali html dan svn-wholename '*.svn*'
daripada-name
..svn
direktori dikecualikan dari hasil pencarian.! -name '.'
harus mengecualikan.
dari hasil pencarian.Saya sudah memiliki masalah yang sama untuk waktu yang lama, dan ada beberapa solusi yang dapat diterapkan dalam situasi yang berbeda:
ack-grep
adalah semacam "pengembanggrep
" yang secara default melompati direktori kontrol versi dan file sementara. Theman
Halaman menjelaskan bagaimana untuk mencari hanya jenis file tertentu dan bagaimana menentukan sendiri .grep
Opsi--exclude
dan miliknya sendiri--exclude-dir
dapat digunakan dengan sangat mudah untuk melewati gumpalan file dan direktori tunggal (sayangnya, tidak ada globbing untuk direktori).find . \( -type d -name '.svn' -o -type f -name '*.html' \) -prune -o -print0 | xargs -0 grep ...
harus bekerja, tetapi opsi di atas mungkin tidak terlalu merepotkan dalam jangka panjang.sumber
find
Perintah berikut tidak memangkas direktori yang namanya berisi.svn
, Meskipun tidak turun ke direktori, nama path yang dipangkas dicetak ... (-name '*.svn'
adalah penyebabnya!) ..Anda dapat memfilter nama direktori melalui:
grep -d skip
yang secara diam-diam melewatkan "nama direktori" input tersebut.Dengan GNU grep, Anda dapat menggunakan
-H
bukan/dev/null
. Sebagai masalah sampingan:\+
bisa jauh lebih cepat daripada\;
, misalnya. untuk 1 juta file satu baris, menggunakannya\;
butuh 4m20s ,\+
hanya butuh 1,2s .Metode berikut menggunakan
xargs
alih-alih-exec
, dan mengasumsikan tidak ada baris baru\n
dalam nama file Anda . Seperti yang digunakan di sini,xargs
sama dengan find\+
.xargs
dapat meneruskan nama-file yang berisi spasi berurutan dengan mengubah pembatas input menjadi'\n'
dengan-d
opsi.Ini mengecualikan direktori yang namanya hanya berisi
.svn
dan menggerogoti file yang tidak diakhiri.html
.sumber
\+
varian aksi -exec. Hore untuk masalah sampingan ringan!+
ini bukan karakter khusus untuk shell, Anda tidak perlu mengetik\
sebelumnya.