xargs
adalah solusi paling fleksibel untuk memisahkan keluaran menjadi argumen perintah.
Ini juga sangat mudah dibaca oleh manusia dan mudah digunakan karena parameterisasinya yang sederhana.
Formatnya adalah xargs -n $NUMLINES mycommand
.
Misalnya, ke echo
setiap baris dalam file /tmp/tmp.txt
Anda akan melakukan:
cat /tmp/tmp.txt | xargs -n 1 echo
Atau ke diff
setiap pasangan file berurutan yang terdaftar sebagai baris dalam file dengan nama di atas yang akan Anda lakukan:
cat /tmp/tmp.txt | xargs -n 2 diff
-n 2
menginstruksikan xargs
untuk menggunakan dan meneruskan sebagai argumen terpisah dua baris dari apa yang telah Anda salurkan sekaligus.
Anda dapat menyesuaikan xargs
untuk membagi pembatas selain carriage return/newline.
Gunakan man xargs
dan google untuk mengetahui lebih lanjut tentang kekuatan utilitas serbaguna ini.
Cara terbaik untuk melakukannya adalah dengan mengalihkan file ke loop:
# Basic idea. Keep reading for improvements.
FILE=test
while read CMD; do
echo "$CMD"
done < "$FILE"
Pengalihan dengan < "$FILE"
memiliki beberapa keunggulan dibandingkan cat "$FILE" | while ...
. Ini menghindari penggunaan cat yang tidak berguna, menyelamatkan proses anak yang tidak perlu. Itu juga menghindari jebakan umum di mana loop berjalan dalam subkulit. Di Bash, perintah dalam |
pipa dijalankan dalam subkulit, yang berarti penugasan variabel hilang setelah loop berakhir. Pengalihan dengan <
tidak mengalami masalah itu, jadi Anda dapat menggunakan $CMD
setelah loop atau memodifikasi variabel lain di dalam loop. Itu juga, sekali lagi, menghindari proses anak yang tidak perlu.
Ada beberapa peningkatan tambahan yang dapat dilakukan:
- Tambahkan
IFS=
sehinggaread
tidak akan memangkas spasi kosong di depan dan di belakang dari setiap baris. - Tambahkan
-r
keread
untuk mencegah garis miring terbalik ditafsirkan sebagai urutan pelarian. - Huruf kecil
CMD
danFILE
. Konvensi Bash adalah bahwa hanya variabel shell lingkungan dan internal yang menggunakan huruf besar. - Gunakan
printf
di tempatecho
mana yang lebih aman jika$cmd
adalah string seperti-n
, yangecho
akan ditafsirkan sebagai bendera.
file=test
while IFS= read -r cmd; do
printf '%s\n' "$cmd"
done < "$file"
Apa yang Anda miliki adalah menyalurkan teks "cat test"
ke dalam lingkaran.
Anda hanya ingin:
cat test | \
while read CMD; do
echo $CMD
done