Anda mungkin ingin membuat panggilan untuk menemukan (sekali, ketika Anda belajar, itu mungkin, yang mungkin hari ini). Ini, tentu saja, hanya mungkin selama Anda tetap menemukan. Setelah Anda melakukan pipe ke xargs, hal itu di luar jangkauan.
Contoh kecil, dua file a.lst dan b.lst:
cat a.lst
fuddel.sh
fiddel.sh
cat b.lst
fuddel.sh
Tidak ada trik di sini - hanya fakta bahwa keduanya mengandung "fuddel" tetapi hanya satu yang mengandung "fiddel".
Asumsikan kita tidak tahu itu. Kami mencari file yang sesuai dengan 2 ketentuan:
find -exec grep -q fuddel {} ";" -exec grep -q fiddel {} ";" -ls
192097 4 -rw-r--r-- 1 stefan stefan 20 Jun 27 17:05 ./a.lst
Yah, mungkin Anda tahu sintaks untuk grep atau program lain untuk melewatkan kedua string sebagai syarat, tapi bukan itu intinya. Setiap program yang dapat mengembalikan benar atau salah, diberikan file sebagai argumen, dapat digunakan di sini - grep hanyalah contoh yang populer.
Dan catatan, Anda dapat mengikuti menemukan exec dengan perintah find lainnya, seperti ls atau -delete atau yang serupa. Catatan, penghapusan itu tidak hanya rm (menghapus file), tetapi rmdir (menghapus direktori) juga.
Rantai seperti itu dibaca sebagai kombinasi AND dari perintah, selama tidak ditentukan (dengan -or
switch) (dan parens (yang perlu ditutup-tutupi)))).
Jadi Anda tidak meninggalkan rantai penemuan, yang merupakan hal yang berguna. Saya tidak melihat adanya keuntungan dalam menggunakan -xargs, karena Anda harus berhati-hati dalam mengirimkan file, yang merupakan sesuatu yang tidak perlu dilakukan - itu secara otomatis menangani melewati setiap file sebagai argumen tunggal untuk Anda.
Jika Anda yakin perlu beberapa penyembunyian untuk menemukan {} kawat gigi , jangan ragu untuk mengunjungi pertanyaan saya yang meminta bukti. Penegasan saya adalah: Anda tidak.
find
. Terima kasih banyak!-exec
cara melakukannyaxargs -P4
agar tiga dari empat core tidak tinggal diam?Memanggil nama file dengan aman
xargs
mengharuskan Andafind
mendukung-print0
opsi dan Andaxargs
memiliki opsi yang sesuai untuk membacanya (--null
atau-0
). Jika tidak, nama file dengan karakter yang tidak diinginkan atau garis miring terbalik atau tanda kutip atau spasi putih dalam nama dapat menyebabkan perilaku yang tidak terduga. Di sisi lain,find -exec {} +
ada dalam spesifikasi POSIXfind
, sehingga portabel, dan ini seamanfind -print0 | xargs -0
, dan pasti lebih aman daripadafind | xargs
. Saya akan merekomendasikan tidak pernah melakukanfind | xargs
tanpanya-print0
.sumber
find … -exec … {} +
adalah OpenBSD, yang hanya memperoleh fitur ini dengan versi 5.1 yang dirilis pada 2012. Semua BSD telah memiliki-print0
selama beberapa tahun, bahkan OpenBSD (meskipun ia menolak fitur itu untuk sementara waktu juga). Solaris, di sisi lain, menempel pada fitur POSIX, sehingga Anda dapat-exec +
dan tidak-print0
.-print0
adalah rasa sakit dan meskipun Anda bisa berdebatxargs --delimiter "\n"
tidak setara, saya belum pernah menggunakan yang pertama setelah menemukan yang terakhir.-0
lebih menyakitkan daripada--delimiter "\n"
.-0
, GNUxargs
perlu-r
menghindari menjalankan perintah jika tidak ada input.| xargs -r0 cmd
adalahcmd
stdin yang terpengaruh (tergantung padaxargs
implementasinya, itu/dev/null
atau pipa.Jika Anda menggunakan
-exec ... ;
formulir (mengingat untuk keluar dari tanda titik koma), Anda menjalankan perintah sekali per nama file. Jika Anda menggunakan-print0 | xargs -0
, Anda menjalankan beberapa perintah per nama file. Anda pasti harus menggunakan-exec +
formulir, yang menempatkan banyak file dalam satu baris perintah dan jauh lebih cepat ketika sejumlah besar file terlibat.Kelebihan menggunakan
xargs
adalah kemampuan untuk menjalankan beberapa perintah secara paralel menggunakanxargs -P
. Pada sistem multi-core, itu dapat memberikan penghematan waktu yang sangat besar.sumber
-P
bukannya-p
. Perlu diingatxargs -P
tidak dalam standar POSIX, sedangkanfind -exec {} +
, yang penting jika Anda ingin portabilitas.find /tmp/ -exec ls "{}" +
berfungsi dengan baik.-exec
sekian lama (saya seorang masokis, saya bahkan tidak menggunakan tanda kutip untuk melarikan diri{}
, saya selalu mengetik\{\}
; jangan bertanya), semuanya sepertinya harus diloloskan sekarang.find /tmp/ -exec ls {} +
tidak akan bekerja.bash
mulai menerima kawat gigi secara verbal. Saya cukup yakin setidaknya salah satu dari kerang tua yang saya gunakan cocok melemparkan hissy jika kawat gigi tidak lolos.Mengenai kinerja saya pikir itu
-exec … +
hanya akan lebih baik karena ini adalah alat tunggal yang melakukan semua pekerjaan tetapi bagian dari dokumentasi GNU findutil mengatakan bahwa-exec … +
mungkin dalam beberapa kasus ini kurang efisien:Saya tidak yakin apa artinya itu, jadi saya bertanya dalam obrolan di mana derobert menjelaskannya sebagai:
(Memformat oleh saya.)
Jadi begitulah. Tetapi jika kinerja benar-benar penting, Anda harus melakukan benchmarking realistis atau bahkan bertanya pada diri sendiri apakah Anda bahkan ingin menggunakan shell untuk kasus tersebut.
Di sini, di situs ini saya pikir lebih baik menyarankan orang untuk menggunakan
-exec … +
formulir kapan pun dimungkinkan karena hanya karena lebih sederhana dan untuk alasan yang disebutkan dalam jawaban lain di sini (misalnya menangani nama file aneh tanpa harus berpikir banyak).sumber