Bagaimana saya bisa membuat xargs mengeksekusi perintah tepat sekali untuk setiap baris input yang diberikan? Perilaku defaultnya adalah memotong-motong baris dan menjalankan perintah sekali, melewati beberapa baris ke setiap instance.
Dari http://en.wikipedia.org/wiki/Xargs :
find / path -type f -print0 | xargs -0 rm
Dalam contoh ini, temukan umpan input xargs dengan daftar panjang nama file. xargs kemudian membagi daftar ini menjadi sublists dan memanggil rm satu kali untuk setiap sublist. Ini lebih efisien daripada versi yang setara secara fungsional ini:
find / path -type f -exec rm '{}' \;
Saya tahu bahwa find memiliki flag "exec". Saya hanya mengutip contoh ilustratif dari sumber lain.
find /path -type f -delete
akan lebih efisien :)Jawaban:
Berikut ini hanya akan berfungsi jika Anda tidak memiliki spasi di input Anda:
dari halaman manual:
sumber
xargs -n 1
seperti yang Anda berikan menunjukkan "daftar argumen terlalu panjang".MAX-LINES
dihilangkan, defaultnya adalah 1,xargs -l
sudah cukup. Lihatinfo xargs
.echo "foo bar" | xargs -n1 echo
. karenanya jika Anda menyambungkan hal-hal seperti 'ls', itu tidak akan menangani ruang dengan baik.-L 1
tidak menjawab pertanyaan asli, dan-n 1
hanya melakukannya dalam salah satu interpretasi yang mungkin. Lihat jawaban panjang saya di bawah ini.-L 1
. Bagi saya, OP tampaknya berusaha menghindari perilaku chunking default, dan karena ini diterima, saya menganggap saya benar. Jawaban Anda membahas kasus penggunaan yang sedikit berbeda di mana Anda menginginkan perilaku chunking juga.Menurut saya semua jawaban yang ada pada halaman ini salah, termasuk yang ditandai sebagai benar. Itu bermula dari fakta bahwa pertanyaan itu kata-kata yang ambigu.
Ringkasan: Jika Anda ingin menjalankan perintah "tepat sekali untuk setiap baris input yang diberikan," melewati seluruh baris (tanpa baris baru) ke perintah sebagai argumen tunggal, maka ini adalah cara terbaik yang kompatibel dengan UNIX untuk melakukannya:
GNU
xargs
mungkin atau mungkin tidak memiliki ekstensi berguna yang memungkinkan Anda untuk menghapustr
, tetapi mereka tidak tersedia pada OS X dan sistem UNIX lainnya.Sekarang untuk penjelasan panjangnya ...
Ada dua masalah yang harus diperhatikan saat menggunakan xargs:
Untuk menguji perilaku xargs, kita memerlukan utilitas yang menunjukkan berapa kali dieksekusi dan dengan berapa banyak argumen. Saya tidak tahu apakah ada utilitas standar untuk melakukan itu, tetapi kita dapat mengkodekannya dengan mudah di bash:
Dengan asumsi Anda menyimpannya
show
di direktori Anda saat ini dan membuatnya dapat dieksekusi, berikut ini cara kerjanya:Sekarang, jika pertanyaan aslinya benar-benar tentang poin 2. di atas (seperti yang saya pikirkan, setelah membacanya beberapa kali) dan harus dibaca seperti ini (perubahan dicetak tebal):
maka jawabannya adalah
-n 1
.Mari kita bandingkan perilaku default xargs, yang membagi input sekitar whitespace dan memanggil perintah sesering mungkin:
dan perilakunya dengan
-n 1
:Jika, di sisi lain, pertanyaan awal adalah tentang poin 1. input terpecah dan harus dibaca seperti ini (banyak orang yang datang ke sini tampaknya berpikir itulah masalahnya, atau membingungkan kedua masalah):
maka jawabannya lebih halus.
Orang akan berpikir itu
-L 1
bisa membantu, tetapi ternyata itu tidak mengubah parsing argumen. Itu hanya mengeksekusi perintah sekali untuk setiap baris input, dengan argumen sebanyak yang ada di baris input:Tidak hanya itu, tetapi jika garis berakhir dengan spasi, itu ditambahkan ke yang berikutnya:
Jelas,
-L
ini bukan tentang mengubah cara xargs membagi input menjadi argumen.Satu-satunya argumen yang melakukannya secara lintas platform (tidak termasuk ekstensi GNU) adalah
-0
, yang membagi input di sekitar byte NUL.Lalu, itu hanya masalah menerjemahkan baris baru ke NUL dengan bantuan
tr
:Sekarang argumen parsing terlihat baik-baik saja, termasuk spasi spasi tambahan.
Akhirnya, jika Anda menggabungkan teknik ini dengan
-n 1
, Anda mendapatkan tepat satu eksekusi perintah per baris input, input apa pun yang Anda miliki, yang mungkin merupakan cara lain untuk melihat pertanyaan asli (mungkin yang paling intuitif, diberi judul):sumber
-L
mengeksekusi perintah satu kali per baris input (tetapi spasi di akhir baris menggabungkannya ke baris berikutnya, dan baris tersebut masih dibagi menjadi argumen sesuai dengan spasi putih); saat-n
menjalankan perintah sekali per argumen input. Jika Anda menghitung jumlah->
dalam contoh output, itu adalah berapa kali script./show
dieksekusi.xargs
mungkin atau mungkin tidak memiliki ekstensi yang berguna yang memungkinkan Anda untuk menghapusnya.tr
Ini memiliki ekstensi yang sangat berguna; fromxargs --help
- -d, --delimiter = CHARACTER item dalam aliran input dipisahkan oleh CHARACTER, bukan oleh spasi; menonaktifkan pemrosesan quote dan backslash dan pemrosesan EOF yang logis-L
.-L
tidak mengatakan berapa kali untuk mengeksekusi skrip per baris, ia mengatakan berapa banyak baris input data untuk dikonsumsi sekaligus.Jika Anda ingin menjalankan perintah untuk setiap baris (yaitu hasil) yang berasal
find
, lalu untuk apa Anda membutuhkannyaxargs
?Mencoba:
find
path-type f -exec
your-command{} \;
di mana literal
{}
diganti dengan nama file dan literal\;
diperlukan untukfind
mengetahui bahwa perintah kustom berakhir di sana.EDIT:
(setelah pengeditan pertanyaan Anda mengklarifikasi yang Anda ketahui
-exec
)Dari
man xargs
:Perhatikan bahwa nama file yang diakhiri dengan kosong akan menyebabkan masalah jika Anda menggunakan
xargs
:Jadi, jika Anda tidak peduli dengan
-exec
opsi tersebut, Anda sebaiknya menggunakan-print0
dan-0
:sumber
-L 1
adalah solusi sederhana tetapi tidak berfungsi jika ada file yang berisi spasi di dalamnya. Ini adalah fungsi utama-print0
argumen find - untuk memisahkan argumen dengan karakter '\ 0' dan bukan spasi putih. Ini sebuah contoh:Solusi yang lebih baik adalah menggunakan
tr
untuk mengonversi baris baru ke\0
karakter null ( ), dan kemudian menggunakanxargs -0
argumen. Ini sebuah contoh:Jika Anda perlu membatasi jumlah panggilan, Anda dapat menggunakan
-n 1
argumen untuk melakukan satu panggilan ke program untuk setiap input:Ini juga memungkinkan Anda untuk menyaring hasil pencarian sebelum mengubah jeda menjadi nol.
sumber
-L
juga adalah bahwa ia tidak mengizinkan beberapa argumen untuk setiapxargs
panggilan perintah."?Alternatif lain ...
sumber
Dua cara ini juga berfungsi, dan akan berfungsi untuk perintah lain yang tidak menggunakan find!
contoh use case:
akan menghapus semua file pyc di bawah direktori ini bahkan jika file pyc berisi spasi.
sumber
itu yang kamu butuhkan.
sumber
Perintah berikut akan menemukan semua file (-type f) di
/path
dan kemudian salin menggunakancp
ke folder saat ini. Perhatikan penggunaan jika-I %
untuk menentukan karakter placeholder dicp
baris perintah sehingga argumen dapat ditempatkan setelah nama file.find /path -type f -print0 | xargs -0 -I % cp % .
Diuji dengan xargs (GNU findutils) 4.4.0
sumber
Anda dapat membatasi jumlah baris, atau argumen (jika ada spasi di antara setiap argumen) menggunakan flag --max-lines atau --max-args.
sumber
Sepertinya saya tidak memiliki reputasi yang cukup untuk menambahkan komentar pada jawaban Tobia di atas , jadi saya menambahkan "jawaban" ini untuk membantu kita yang ingin bereksperimen dengan
xargs
cara yang sama pada platform Windows.Ini adalah file batch windows yang melakukan hal yang sama dengan script "show" Tobia yang cepat dikodekan:
sumber
Jawaban @raemon tampaknya benar dengan "-0" bahkan dengan ruang dalam file.
Saya sedang mencoba perintah xargs dan saya menemukan bahwa "-0" berfungsi sempurna dengan "-L". bahkan spasi diperlakukan (jika input diakhiri nol). berikut ini adalah contohnya:
Berikut ini akan membagi nulls dan menjalankan perintah pada setiap argumen dalam daftar:
jadi
-L1
akan mengeksekusi argumen pada setiap karakter null yang dihentikan jika digunakan dengan "-0". Untuk melihat perbedaannya cobalah:bahkan ini akan dijalankan sekali:
Perintah akan dieksekusi sekali karena "-L" sekarang tidak terpecah pada byte nol. Anda harus memberikan "-0" dan "-L" agar berfungsi.
sumber
Dalam contoh Anda, titik pemipaan output find ke xargs adalah perilaku standar opsi -exec find adalah untuk mengeksekusi perintah satu kali untuk setiap file yang ditemukan. Jika Anda menggunakan find, dan Anda menginginkan perilaku standarnya, maka jawabannya sederhana - jangan gunakan xargs untuk memulai.
sumber
find
, dan itulah sebabnya mereka tidak suka-exec
pilihan.jalankan tugas semut bersih-bersih pada setiap build.xml pada saat ini atau sub-folder.
sumber
ant
menginstal.