Saya menggunakan find
dan mendapatkan daftar file yang ingin saya grep
lalui. Bagaimana cara saya mem-pipe list itu grep
?
Nah, kasus umum yang bekerja dengan perintah apa pun yang menulis ke stdout adalah menggunakan xargs
, yang akan memungkinkan Anda melampirkan sejumlah argumen baris perintah ke akhir perintah:
$ find … | xargs grep 'search'
Atau untuk menanamkan perintah di grep
baris Anda dengan backticks atau $()
, yang akan menjalankan perintah dan mengganti hasilnya:
$ grep 'search' $(find …)
Perhatikan bahwa perintah ini tidak berfungsi jika nama file berisi spasi, atau "karakter aneh" tertentu lainnya ( \'"
untuk xargs, \[*?
untuk $(find …)
).
Namun, dalam kasus khusus find
kemampuan untuk mengeksekusi program pada argumen yang diberikan adalah bawaan:
$ find … -exec grep 'search' {} \;
Segala sesuatu di antara -exec
dan ;
merupakan perintah untuk dijalankan; {}
diganti dengan nama file yang ditemukan oleh find
. Itu akan mengeksekusi terpisah grep
untuk setiap file; karena grep
dapat mengambil banyak nama file dan mencari semuanya, Anda dapat mengubah ;
to +
to tell find untuk meneruskan semua nama file yang cocok grep
sekaligus:
$ find … -exec grep 'search' {} \+
find ... -type f -print0 | xargs -r0 grep 'search' /dev/null
. QED. Meskipun-exec +
sangat efisien, itu tidak ada di semua versi find.-exec
, daripadaxargs
. Jika Anda menggunakan-exec
difind
, itu akan membuat hanya satu shell ke grep untuk konten. Jika Anda menggunakanxargs
, itu akan membuat dua cangkang: satu untukfind
dan yang lain untukxargs
.$ find … -exec grep 'search' {} \+
formulir jauh lebih cepat.Beberapa versi
grep
(misalnya pada Linux yang tidak tertanam atau BSD atau Mac OS X) memiliki-r
opsi untuk melakukan pencarian rekursif. Pada OpenBSD, gunakan-R
(dan tidak ada--exclude
seperti pada contoh di bawah). Ini mencakup kombinasi sederhanafind
dengangrep
.Jika implementasi Anda tidak memiliki
-R
bendera, atau jika Anda ingin kriteria pencocokan file yang lebih bagus, Anda dapat menggunakan-exec
utamafind
untuk membuatnya mengeksekusigrep
. Beberapafind
implementasi lama tidak mendukung-exec
...+
; pada sistem ini, gunakan;
bukan+
(ini akan memanggilgrep
sekali per file, jadi akan lebih lambat, tetapi jika tidak hasilnya akan sama). Perhatikan/dev/null
trik yang menyebabkangrep
menampilkan nama file bahkan jika kebetulan dipanggil pada satu file (grep GNU dan grep FreeBSD / NetBSD / OSX memiliki-H
opsi untuk mencapai efek yang sama).sumber
GNU grep
memiliki-H
opsi untuk selalu mencetak nama file.