xargs --replace / -I untuk argumen tunggal

10

Saya mencoba menggunakan xargs untuk menjalankan perintah untuk setiap argumen yang diberikan, tetapi sayangnya flag --replace / -I tampaknya tidak berfungsi dengan baik ketika dikonjugasikan dengan -n. Tampaknya {} akan berkembang menjadi daftar argumen lengkap yang dibaca dari stdin, terlepas dari opsi -n.

Sayangnya semua contoh di web tampaknya untuk perintah (mv, cp, rm) yang akan mengambil banyak argumen di mana {} diperluas.

Misalnya, saat menjalankan:

echo a b c d | xargs -n 1 -I {} echo derp {}

Outputnya adalah:

derp a b c d

Tapi saya berharap:

derp a
derp b
derp c
derp d

Namun, menjalankannya tanpa -I {} menghasilkan hasil yang diharapkan:

echo a b c d | xargs -n 1 echo derp
derp a
derp b
derp c
derp d

Apakah ada cara untuk mencapai ini dengan xargs? Tujuan utama saya adalah menggunakannya untuk menjalankan beberapa sesi (parralel) ssh, misalnya

echo server{1..90} | xargs -n 1 -P 0 -I {} ssh {} 'echo $SOME_HOST_INFO'

Saya menjalankan xargs (GNU findutils) 4.4.2di RHEL 6.3.

André Fernandes
sumber
2
Menariknya itu bekerja seperti yang Anda berniat dengan BSD xargs, tapi tidak GNU xargs.
slhck
1
man xargspada -I: Also, unquoted blanks do not terminate input items; instead the separator is the newline character. Implies -x and -L 1.Jadi berperilaku seperti yang dirancang.
Daniel Beck
@ André, karena niat Anda adalah menjalankan taks secara paralel, sudahkah Anda melihat GNU parallel? Itu melakukan pekerjaan dengan baik. Penafian: Saya mengemasnya untuk Debian.
rbrito
Paralel GNU sepertinya merupakan pengganti yang baik, tetapi sayangnya saya tidak dapat menginstalnya pada host khusus ini.
André Fernandes
@ AndréFernandes Bisakah Anda menguraikan jika alasan Anda tidak dicakup oleh oletange.blogspot.dk/2013/04/why-not-install-gnu-parallel.html
Ole Tange

Jawaban:

5

Anda dapat bergaung dengan baris baru untuk mencapai hasil yang diharapkan. Dalam kasus Anda dengan ekspansi server yang akan menjadi:

$ echo -e server{1..4}"\n" | xargs -I{} echo derp {}
derp server1
derp server2
derp server3
derp server4
ahilsend
sumber
Gagasan baris baru mengatasi masalah (tidak hanya dengan contoh persis Anda): echo server {1..4} | tr '' '\ n' | xargs -I {} echo derp {} derp server1 derp server2 derp server3 derp server4
André Fernandes
Maaf, mengujinya dengan zsh... Memperbaiki jawaban saya. echomembutuhkan -eopsi.
ahilsend
2

Anda dapat menggunakan pipa tambahan seperti ini,

echo a b c d | xargs -n1 | xargs -I{} echo derp {}
derp a
derp b
derp c
derp d

Penggunaan perantara dari 'gema' masing-masing xargs 'abcd' secara individual karena opsi '-n1'. Ini menempatkan setiap huruf pada barisnya sendiri seperti ini,

echo a b c d | xargs -n1
a
b
c
d 

Sangat penting untuk dipahami ketika menggunakan -I (penggantian string), xargs menyiratkan -L, yang mengeksekusi perintah utilitas (dalam kasus Anda gema) sekali per baris. Juga, Anda tidak dapat menggunakan -n dengan -L karena keduanya saling eksklusif.

synergy77
sumber