Saya ingin menjalankan perintah java sekali untuk setiap pertandingan ls | grep pattern -
. Dalam hal ini, saya pikir saya bisa melakukannya find pattern -exec java MyProg '{}' \;
tetapi saya ingin tahu tentang kasus umum - apakah ada cara mudah untuk mengatakan "jalankan perintah sekali untuk setiap baris input standar"? (Dalam ikan atau bash.)
162
printf "foo bar\nbaz bat" | xargs echo whee
akan menghasilkanwhee foo bar baz bat
. Mungkin menambahkan opsi-L
atau-n
?Jawaban yang diterima memiliki ide yang tepat, tetapi kuncinya adalah untuk lulus
xargs
dengan-n1
switch, yang berarti "Jalankan perintah sekali per baris output:"Atau, untuk file input tunggal Anda dapat menghindari pipa dari
cat
seluruhnya dan hanya pergi dengan:sumber
xargs
untuk tidak berjalan jikastdin
kosong--no-run-if-empty
-r
:: Jika input standar tidak mengandung nonblank, jangan jalankan perintah. Biasanya, perintah dijalankan sekali walaupun tidak ada input. Opsi ini adalah ekstensi GNU.command
?Di Bash atau shell Bourne-style lainnya (abu, ksh, zsh, ...):
read -r
membaca satu baris dari input standar (read
tanpa-r
menginterpretasikan garis miring terbalik, Anda tidak menginginkannya). Dengan demikian Anda dapat melakukan salah satu dari yang berikut:sumber
tail -f syslog | grep -e something -e somethingelse| while read line; do echo $line; done
tidak berhasil. Ini bekerja dengan file yang disalurkan kewhile
loop, bekerja dengan hanyatail -f
, bekerja dengan adilgrep
, tetapi tidak dengan kedua pipa. Memberikangrep
yang--line-buffered
pilihan membuatnya bekerjacommand | while read -r line; do echo "$line" | command ; done
Saya setuju dengan Keith, xargs adalah alat paling umum untuk pekerjaan itu.
Saya biasanya menggunakan pendekatan 3 langkah.
Ada cara yang lebih kecil dan lebih cepat, tetapi cara ini hampir selalu berhasil.
Contoh sederhana:
2 baris pertama memilih beberapa file untuk dikerjakan, kemudian awk menyiapkan string yang bagus dengan perintah untuk dieksekusi dan beberapa argumen dan $ 1 adalah input kolom pertama dari pipa. Dan akhirnya saya memastikan bahwa xargs mengirimkan string ini ke bash yang baru saja menjalankannya.
Ini sedikit berlebihan, tetapi resep ini telah membantu saya di banyak tempat karena sangat fleksibel.
sumber
xargs -0
gunakan byte nol sebagai pemisah rekaman, jadi pernyataan cetak awk Anda seharusnyaprintf("MyJavaProg --args \"%s\"\0",$1)
awk
Anda dapat memilikinya melakukan pertandingan pola dan melewatkangrep
eg,ls | awk '/xls/ {print...
GNU Parallel dibuat untuk tugas semacam itu. Penggunaan paling sederhana adalah:
Tonton video intro untuk mempelajari lebih lanjut: http://www.youtube.com/watch?v=OpaiGYxkSuQ
sumber
cat
sini karenagrep
dapat langsung membaca file< stuff grep pattern
tetapigrep pattern stuff
tanpa redirection atau cat sama sekali. Namun, itu tidak secara material mengubah argumen Anda dan jika Anda pikir lebih jelas untuk selalu menggunakan hal-hal dalam pipa yang dimulai dengancat
, maka berkuasa untuk AndaJuga,
while read
loop dalam cangkang ikan (saya berasumsi Anda ingin cangkang ikan, mengingat Anda menggunakan tag ikan ).Beberapa poin yang perlu diperhatikan.
read
tidak mengambil-r
argumen, dan itu tidak menafsirkan backslash Anda, untuk membuat use case paling umum mudah.$line
, karena tidak seperti bash, ikan tidak memisahkan variabel dengan spasi.command
dengan sendirinya adalah kesalahan sintaks (untuk menangkap penggunaan argumen placeholder seperti itu). Ganti dengan perintah asli.sumber
while
perlu dipasangkan dengando
&done
bukanend
?Jika Anda perlu mengontrol di mana tepatnya argumen input dimasukkan ke dalam baris perintah Anda atau jika Anda perlu mengulanginya beberapa kali maka Anda perlu menggunakannya
CONTOH 1xargs -I{}
.Buat struktur folder kosong di
CONTOH # 2another_folder
yang mencerminkan subfolder di direktori saat ini:Terapkan operasi pada daftar file yang berasal dari stdin, dalam hal ini buat salinan dari setiap
.html
file dengan menambahkan.bak
ekstensi:Dari
xargs
halaman manual untuk MacOS / BSD :xargs
Halaman manual Linux :sumber
Ketika berhadapan dengan input yang berpotensi tidak bersih, saya suka melihat seluruh pekerjaan 'terbilang' baris demi baris untuk inspeksi visual sebelum saya menjalankannya (terutama ketika sesuatu yang merusak seperti membersihkan kotak surat orang).
Jadi yang saya lakukan adalah membuat daftar parameter (mis. Nama pengguna), memasukkannya ke file dengan mode satu-catatan-per-baris, seperti ini:
Lalu saya membuka daftar
vim
, dan memotong-motongnya dengan mencari dan mengganti ekspresi sampai saya mendapatkan daftar perintah lengkap yang perlu dijalankan, seperti ini:Dengan cara ini jika regex Anda tidak lengkap, Anda akan melihat perintah apa yang akan memiliki masalah potensial (mis.
/bin/rm -fr johnnyo connor
). Dengan cara ini Anda dapat membatalkan regex Anda, dan coba lagi dengan versi yang lebih andal. Nama mangling terkenal karena hal ini, karena sulit untuk mengurus semua kasus tepi seperti Van Gogh, O'Connors, St. Clair, Smith-Wesson.Memiliki
set hlsearch
berguna untuk melakukan inivim
, karena akan menyoroti semua pertandingan, sehingga Anda dapat dengan mudah melihat jika tidak cocok, atau cocok dengan cara yang tidak disengaja.Setelah regex Anda sempurna dan menangkap semua case yang dapat Anda uji / pikirkan, maka saya biasanya mengonversinya menjadi ekspresi sed sehingga dapat sepenuhnya otomatis untuk dijalankan lagi.
Untuk kasus di mana jumlah baris input mencegah Anda melakukan inspeksi visual, saya sangat merekomendasikan untuk mengulangi perintah ke layar (atau lebih baik, log) sebelum dieksekusi, jadi jika kesalahan keluar, Anda tahu persis perintah yang menyebabkan itu gagal. Kemudian Anda dapat kembali ke regex asli dan menyesuaikannya sekali lagi.
sumber
Jika suatu program mengabaikan pipa tetapi menerima file sebagai argumen, maka Anda bisa mengarahkannya ke file khusus
/dev/stdin
.Saya tidak terbiasa dengan java, tapi di sini adalah contoh bagaimana Anda akan melakukannya untuk bash:
$ Diperlukan untuk bash menerjemahkan
\n
ke dalam baris baru. Saya tidak yakin mengapa.sumber
Saya lebih suka ini - memungkinkan perintah multi-line dan menghapus kode
ref https://stackoverflow.com/a/3891678/248616
sumber
Di sini, copypaste Anda dapat langsung digunakan:
Item dari daftar akan diletakkan di tempat {} berada dan seluruh perintah dan parameter akan digunakan apa adanya.
sumber