Saya melakukan finddan kemudian mendapatkan daftar file. Bagaimana cara saya catmengirim pipa ke utilitas lain seperti (sehingga kucing menampilkan konten semua file itu) dan pada dasarnya perlu grepsesuatu dari file-file ini.
Saya melakukan finddan kemudian mendapatkan daftar file. Bagaimana cara saya catmengirim pipa ke utilitas lain seperti (sehingga kucing menampilkan konten semua file itu) dan pada dasarnya perlu grepsesuatu dari file-file ini.
Jawaban:
Perpipaan ke proses lain (Meskipun ini TIDAK AKAN mencapai apa yang Anda katakan Anda coba lakukan):
command1 | command2
Ini akan mengirim output dari command1 sebagai input dari command2
-execpada find(ini akan melakukan apa yang ingin Anda lakukan - tetapi khusus untuk find)
find . -name '*.foo' -exec cat {} \;
(Segala sesuatu di antara finddan -execadalah predikat find yang sudah Anda gunakan. {}Akan mengganti file tertentu yang Anda temukan dalam perintah ( cat {}dalam hal ini); \;adalah untuk mengakhiri -execperintah.)
mengirim output dari satu proses sebagai argumen baris perintah ke proses lain
command2 `command1`
sebagai contoh:
cat `find . -name '*.foo' -print`
(Perhatikan ini adalah BACK-QUOTES bukan kutipan reguler (di bawah tilde ~ di keyboard saya).) Ini akan mengirimkan output command1menjadi command2sebagai argumen baris perintah. Perhatikan bahwa nama file yang mengandung spasi (baris baru, dll) akan dipecah menjadi argumen yang terpisah.
findmemungkinkan Anda untuk menulis:, di find . -name '*.foo' -exec cat {} +mana +menunjukkan bahwa findharus mengelompokkan sebanyak mungkin nama file ke dalam satu permintaan perintah tunggal. Ini cukup berguna (ini berkaitan dengan spasi dll dalam nama file tanpa menggunakan -print0dan xargs -0).
find . -name '*.foo' | xargs cat
find . -name '*.foo' | xargs cat | grep string
POSIX 2008 menambahkan +penanda findyang berarti sekarang secara otomatis mengelompokkan file sebanyak yang masuk akal ke dalam satu eksekusi perintah, sangat mirip xargs, tetapi dengan sejumlah keuntungan:
Masalah nama file adalah masalah xargstanpa -0opsi, dan masalah 'run even with zero file names' adalah masalah dengan atau tanpa -0opsi - tetapi GNU xargsmemiliki -ratau --no-run-if-emptyopsi untuk mencegah hal itu terjadi. Juga, notasi ini mengurangi jumlah proses, bukan berarti Anda cenderung mengukur perbedaan kinerja. Karenanya, Anda dapat menulis dengan bijaksana:
find . -exec grep something {} +
find . -print | xargs grep something
Jika Anda menggunakan Linux atau memiliki GNU finddan xargsperintah, gunakan -print0dengan finddan -0dengan xargsuntuk menangani nama file yang berisi spasi dan karakter ganjil lainnya.
find . -print0 | xargs -0 grep something
grepJika Anda tidak ingin nama file (hanya teks) maka tambahkan opsi yang sesuai untuk grep(biasanya -huntuk menekan 'judul'). Untuk benar-benar menjamin nama file dicetak oleh grep(bahkan jika hanya satu file ditemukan, atau doa terakhir grephanya diberikan 1 nama file), kemudian tambahkan /dev/nullke xargsbaris perintah, sehingga akan selalu ada setidaknya dua nama file.
xargs grep something.
finddisalurkan ke input standar xargs. The xargsprogram membaca masukan standar, membelah input di ruang putih (kosong, baris baru, tab, dll) dan menambahkan sejumlah kata-kata untuk perintah grep somethingdan mengeksekusi baris perintah. xargskemudian melanjutkan membaca input dan mengeksekusi perintah sampai kehabisan input. xargsmenjalankan grepperintah sesering yang diperlukan untuk input yang diberikan (dari finddalam contoh ini).
/dev/nullkehilangan pesan kesalahan.
Ada beberapa cara untuk meneruskan daftar file yang dikembalikan oleh findperintah ke catperintah, meskipun secara teknis tidak semua menggunakan perpipaan, dan tidak ada yang benar-benar disalurkan langsung ke cat.
Yang paling sederhana adalah menggunakan backticks ( `):
cat `find [whatever]`
Ini mengambil output finddan secara efektif menempatkannya di baris perintah cat. Ini tidak berfungsi dengan baik jika findmemiliki terlalu banyak output (lebih dari yang bisa muat pada baris perintah) atau jika output memiliki karakter khusus (seperti spasi).
Dalam beberapa shell, termasuk bash, seseorang dapat menggunakan $()bukannya backticks:
cat $(find [whatever])
Ini kurang portabel, tetapi bisa ditumpuk. Selain itu, ia memiliki banyak peringatan yang sama dengan backticks.
Karena menjalankan perintah lain pada apa yang ditemukan adalah penggunaan umum find, find memiliki -exectindakan yang mengeksekusi perintah untuk setiap file yang ditemukan:
find [whatever] -exec cat {} \;
The {}adalah sebuah tempat untuk nama file, dan \;menandai akhir perintah (Ini mungkin untuk memiliki tindakan lain setelah-exec .)
Ini akan berjalan catsekali untuk setiap file tunggal daripada menjalankan satu contoh catmelewati itu beberapa nama file yang bisa tidak efisien dan mungkin tidak memiliki perilaku yang Anda inginkan untuk beberapa perintah (meskipun itu baik untuk cat). Sintaksnya juga canggung untuk mengetik - Anda harus keluar dari titik koma karena titik koma khusus untuk shell!
Beberapa versi find(terutama versi GNU) memungkinkan Anda mengganti ;dengan +menggunakan -execmode tambahkan untuk menjalankan lebih sedikit contoh cat:
find [whatever] -exec cat {} +
Ini akan memberikan beberapa nama file ke setiap permintaan cat, yang bisa lebih efisien.
Perhatikan bahwa ini tidak dijamin untuk menggunakan doa tunggal. Jika baris perintah terlalu panjang maka argumen tersebar di beberapa permintaan cat. Untuk catini mungkin bukan masalah besar, tetapi untuk beberapa perintah lain ini dapat mengubah perilaku dengan cara yang tidak diinginkan. Pada sistem Linux, batas panjang baris perintah cukup besar, sehingga pemisahan menjadi beberapa pemanggilan cukup jarang dibandingkan dengan beberapa OS lainnya.
Pendekatan klasik / portabel adalah dengan menggunakan xargs:
find [whatever] | xargs cat
xargsmenjalankan perintah yang ditentukan ( cat, dalam kasus ini), dan menambahkan argumen berdasarkan apa yang dibaca dari stdin. Sama seperti -execdengan +, ini akan memecah baris perintah jika perlu. Artinya, jika findmenghasilkan terlalu banyak output, itu akan berjalan catbeberapa kali. Seperti disebutkan di bagian tentang -execsebelumnya, ada beberapa perintah di mana pemisahan ini dapat mengakibatkan perilaku yang berbeda. Perhatikan bahwa menggunakan xargsseperti ini memiliki masalah dengan spasi dalam nama file, karena xargshanya menggunakan spasi sebagai pembatas.
Metode yang paling kuat, portabel, dan efisien juga menggunakan xargs:
find [whatever] -print0 | xargs -0 cat
The -print0bendera mengatakan finduntuk menggunakan \0(null karakter) pembatas antara nama file, dan -0bendera mengatakan xargsuntuk mengharapkan ini \0pembatas. Ini memiliki perilaku yang hampir sama dengan pendekatan -exec... +, meskipun lebih portabel (tapi sayangnya lebih bertele-tele).
lsjuga.
$()Juga bekerja dengan perintah selain find .
Kedengarannya seperti pekerjaan untuk skrip shell bagi saya:
for file in 'find -name *.xml'
do
grep 'hello' file
done
atau semacam itu
Perintah find memiliki argumen -exec yang dapat Anda gunakan untuk hal-hal seperti ini, Anda bisa melakukan grep secara langsung menggunakan itu.
Misalnya ( dari sini, contoh bagus lainnya di halaman ini ):
find . -exec grep "www.athabasca" '{}' \; -print
Dalam bash, berikut ini akan sesuai:
find /dir -type f -print0 | xargs -0i cat {} | grep whatever
Ini akan menemukan semua file di /dirdirektori, dan memasukkan nama file xargsdengan aman, yang akan dikendarai dengan aman grep.
Melewati xargsbukanlah ide yang baik jika Anda memiliki ribuan file /dir; catakan rusak karena panjang daftar argumen yang berlebihan. xargsakan menyelesaikan semua itu untuk Anda.
The -print0argumen untuk findjerat dengan -0argumen untuk xargsmenangani nama file dengan spasi benar. The -iargumen untuk xargsmemungkinkan Anda untuk memasukkan nama file di mana diperlukan dalam catbaris perintah. Tanda kurung diganti dengan nama file yang disalurkan ke catperintah dari find.
Ini bekerja untuk saya
find _CACHE_* | while read line; do
cat "$line" | grep "something"
done
Ini akan mencetak nama dan isi file-hanya secara rekursif ..
find . -type f -printf '\n\n%p:\n' -exec cat {} \;
Edit (Versi yang ditingkatkan): Ini akan mencetak nama dan isi file teks (ascii) saja secara rekursif ..
find . -type f -exec grep -Iq . {} \; -print | xargs awk 'FNR==1{print FILENAME ":" $0; }'
Satu upaya lagi
find . -type f -exec grep -Iq . {} \; -printf "\n%p:" -exec cat {} \;
Apakah Anda mencoba menemukan teks dalam file? Anda cukup menggunakan grep untuk itu ...
grep searchterm *
Untuk membuat daftar dan melihat isi semua file abc.def pada server di direktori / ghi dan / jkl
find /ghi /jkl -type f -name abc.def 2> /dev/null -exec ls {} \; -exec cat {} \;
Untuk membuat daftar file abc.def yang telah mengomentari entri dan tampilan, lihat entri tersebut di direktori / ghi dan / jkl
find /ghi /jkl -type f -name abc.def 2> /dev/null -exec grep -H ^# {} \;
find -name '*.foo' -printbekerja sangat baik untuk saya ... Terima kasih