Saya melakukan find
dan kemudian mendapatkan daftar file. Bagaimana cara saya cat
mengirim pipa ke utilitas lain seperti (sehingga kucing menampilkan konten semua file itu) dan pada dasarnya perlu grep
sesuatu dari file-file ini.
Saya melakukan find
dan kemudian mendapatkan daftar file. Bagaimana cara saya cat
mengirim pipa ke utilitas lain seperti (sehingga kucing menampilkan konten semua file itu) dan pada dasarnya perlu grep
sesuatu 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
-exec
pada find
(ini akan melakukan apa yang ingin Anda lakukan - tetapi khusus untuk find
)
find . -name '*.foo' -exec cat {} \;
(Segala sesuatu di antara find
dan -exec
adalah predikat find yang sudah Anda gunakan. {}
Akan mengganti file tertentu yang Anda temukan dalam perintah ( cat {}
dalam hal ini); \;
adalah untuk mengakhiri -exec
perintah.)
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 command1
menjadi command2
sebagai argumen baris perintah. Perhatikan bahwa nama file yang mengandung spasi (baris baru, dll) akan dipecah menjadi argumen yang terpisah.
find
memungkinkan Anda untuk menulis:, di find . -name '*.foo' -exec cat {} +
mana +
menunjukkan bahwa find
harus mengelompokkan sebanyak mungkin nama file ke dalam satu permintaan perintah tunggal. Ini cukup berguna (ini berkaitan dengan spasi dll dalam nama file tanpa menggunakan -print0
dan xargs -0
).
find . -name '*.foo' | xargs cat
find . -name '*.foo' | xargs cat | grep string
POSIX 2008 menambahkan +
penanda find
yang 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 xargs
tanpa -0
opsi, dan masalah 'run even with zero file names' adalah masalah dengan atau tanpa -0
opsi - tetapi GNU xargs
memiliki -r
atau --no-run-if-empty
opsi 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 find
dan xargs
perintah, gunakan -print0
dengan find
dan -0
dengan xargs
untuk menangani nama file yang berisi spasi dan karakter ganjil lainnya.
find . -print0 | xargs -0 grep something
grep
Jika Anda tidak ingin nama file (hanya teks) maka tambahkan opsi yang sesuai untuk grep
(biasanya -h
untuk menekan 'judul'). Untuk benar-benar menjamin nama file dicetak oleh grep
(bahkan jika hanya satu file ditemukan, atau doa terakhir grep
hanya diberikan 1 nama file), kemudian tambahkan /dev/null
ke xargs
baris perintah, sehingga akan selalu ada setidaknya dua nama file.
xargs grep something
.
find
disalurkan ke input standar xargs
. The xargs
program membaca masukan standar, membelah input di ruang putih (kosong, baris baru, tab, dll) dan menambahkan sejumlah kata-kata untuk perintah grep something
dan mengeksekusi baris perintah. xargs
kemudian melanjutkan membaca input dan mengeksekusi perintah sampai kehabisan input. xargs
menjalankan grep
perintah sesering yang diperlukan untuk input yang diberikan (dari find
dalam contoh ini).
/dev/null
kehilangan pesan kesalahan.
Ada beberapa cara untuk meneruskan daftar file yang dikembalikan oleh find
perintah ke cat
perintah, 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 find
dan secara efektif menempatkannya di baris perintah cat
. Ini tidak berfungsi dengan baik jika find
memiliki 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 -exec
tindakan 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 cat
sekali untuk setiap file tunggal daripada menjalankan satu contoh cat
melewati 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 -exec
mode 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 cat
ini 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
xargs
menjalankan perintah yang ditentukan ( cat
, dalam kasus ini), dan menambahkan argumen berdasarkan apa yang dibaca dari stdin. Sama seperti -exec
dengan +
, ini akan memecah baris perintah jika perlu. Artinya, jika find
menghasilkan terlalu banyak output, itu akan berjalan cat
beberapa kali. Seperti disebutkan di bagian tentang -exec
sebelumnya, ada beberapa perintah di mana pemisahan ini dapat mengakibatkan perilaku yang berbeda. Perhatikan bahwa menggunakan xargs
seperti ini memiliki masalah dengan spasi dalam nama file, karena xargs
hanya menggunakan spasi sebagai pembatas.
Metode yang paling kuat, portabel, dan efisien juga menggunakan xargs
:
find [whatever] -print0 | xargs -0 cat
The -print0
bendera mengatakan find
untuk menggunakan \0
(null karakter) pembatas antara nama file, dan -0
bendera mengatakan xargs
untuk mengharapkan ini \0
pembatas. Ini memiliki perilaku yang hampir sama dengan pendekatan -exec
... +
, meskipun lebih portabel (tapi sayangnya lebih bertele-tele).
ls
juga.
$()
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 /dir
direktori, dan memasukkan nama file xargs
dengan aman, yang akan dikendarai dengan aman grep
.
Melewati xargs
bukanlah ide yang baik jika Anda memiliki ribuan file /dir
; cat
akan rusak karena panjang daftar argumen yang berlebihan. xargs
akan menyelesaikan semua itu untuk Anda.
The -print0
argumen untuk find
jerat dengan -0
argumen untuk xargs
menangani nama file dengan spasi benar. The -i
argumen untuk xargs
memungkinkan Anda untuk memasukkan nama file di mana diperlukan dalam cat
baris perintah. Tanda kurung diganti dengan nama file yang disalurkan ke cat
perintah 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' -print
bekerja sangat baik untuk saya ... Terima kasih