it-swarm-id.com

Bagaimana cara melewati daftar file untuk di-grep

Saya menggunakan find dan mendapatkan daftar file yang ingin saya sampaikan grep. Bagaimana cara saya mem-pipe daftar itu ke grep?

105
MageProspero

Nah, kasus umum yang bekerja dengan perintah apa pun yang menulis ke stdout adalah menggunakan xargs, yang memungkinkan Anda melampirkan sejumlah argumen baris perintah di akhir perintah:

$ find … | xargs grep 'search'

Atau untuk menanamkan perintah di grep 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 putih, atau "karakter aneh" tertentu lainnya (\'" Untuk xargs, \[*? Untuk $(find …)).


Namun, dalam kasus spesifik find kemampuan untuk menjalankan program pada argumen yang diberikan sudah ada:

$ find … -exec grep 'search' {} \;

Segala sesuatu di antara -exec Dan ; Adalah perintah untuk dieksekusi; {} Diganti dengan nama file yang ditemukan oleh find. Itu akan menjalankan grep yang terpisah untuk setiap file; karena grep dapat mengambil banyak nama file dan mencari semuanya, Anda dapat mengubah ; menjadi + untuk memberi tahu find untuk meneruskan semua nama file yang cocok ke grep di sekali:

$ find … -exec grep 'search' {} \+
126
Michael Mrozek

Beberapa versi grep (mis. Pada Linux yang tidak tertanam atau BSD atau Mac OS X) memiliki -r pilihan untuk melakukan pencarian rekursif. Di OpenBSD, gunakan -R (dan tidak ada --exclude seperti pada contoh di bawah ini). Ini mencakup kombinasi sederhana dari find dengan grep.

Jika implementasi Anda tidak memiliki -R flag, atau jika Anda ingin kriteria pencocokan file yang lebih bagus, Anda dapat menggunakan -exec primer dari find untuk menjalankannya grep. Beberapa implementasi find yang lebih tua tidak mendukung -exec ... +; pada sistem ini, gunakan ; bukannya + (ini akan memanggil grep sekali per file, jadi akan lebih lambat, tetapi jika tidak hasilnya akan sama). Catat /dev/null trik untuk menyebabkan grep untuk 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).

find . -type f -name '*.o' -Prune -o -exec grep 'needle' /dev/null {} +
grep -r --exclude='*.o' 'needle' .