Misalkan saya memiliki beberapa output dari perintah (seperti ls -1
):
a
b
c
d
e
...
Saya ingin menerapkan perintah (katakanlah echo
) untuk masing-masing, pada gilirannya. Misalnya
echo a
echo b
echo c
echo d
echo e
...
Apa cara termudah untuk melakukannya di bash?
ls -1
mungkin menjadi contoh di sini tetapi penting untuk diingat bahwa itu tidak baik untuk mengurai output darils
. Lihat: mywiki.wooledge.org/ParsingLsJawaban:
Mungkin paling mudah digunakan
xargs
. Dalam kasus Anda:The
-L
bendera memastikan input dibaca dengan benar. Dari halaman manual darixargs
:sumber
ls
secara otomatis tidak-1
dalam pipa.ls | xargs -L2 echo
danls -1 | xargs -L2 echo
memberikan dua output yang berbeda. Yang pertama semuanya dalam satu baris.xargs
hanya dapat menjalankan file yang dapat dieksekusi bukan fungsi shell atau perintah built-in shell. Untuk yang pertama solusi terbaik mungkin adalah yang adaread
dalam satu lingkaran.-L1
.Anda dapat menggunakan operasi dasar awal di setiap baris:
Atau Anda dapat menyalurkan output ke sed untuk operasi yang lebih kompleks:
sumber
sh: cho: not found a sh: cho: not found
Sepertinya itu mengambile
gema in menjadi perintah sed atau sesuatu.while
loop.cmd1 | while read line; do cmd2 $line; done
. Atauwhile read line; do cmd2 $line; done < <(cmd1)
yang tidak membuat subkulit. Ini adalah versi sederhana darised
perintah Anda :sed 's/.*/echo &/'
"$line"
di loop sementara, untuk menghindari pemisahan kata.read -r line
untuk mencegahread
bermain-main dengan karakter yang kabur. Misalnyaecho '"a \"nested\" quote"' | while read line; do echo "$line"; done
memberi"a "nested" quote"
, yang telah hilang melarikan diri. Jika kita melakukannya,echo '"a \"nested\" quote"' | while read -r line; do echo "$line"; done
kita mendapatkan"a \"nested\" quote"
seperti yang diharapkan. Lihat wiki.bash-hackers.org/commands/builtin/readAnda bisa menggunakan for for :
Perhatikan bahwa jika perintah yang dimaksud menerima beberapa argumen, maka menggunakan xargs hampir selalu lebih efisien karena hanya perlu menelurkan utilitas yang dipermasalahkan sekali daripada beberapa kali.
sumber
printf '%s\0' * | xargs -0 ...
- Jika tidak, itu tidak aman dengan nama file dengan spasi, tanda kutip, dll.Anda sebenarnya dapat menggunakan sed untuk melakukannya, asalkan GNU sed.
Bagaimana itu bekerja:
sumber
cat /logs/lfa/Modified.trace.log.20150904.pw | sed -r 's/^(.*)(\|006\|00032\|)(.*)$/echo "\1\2\3 - ID `shuf -i 999-14999 -n 1`"/e'
Jika cmd memiliki output besar:
sumber
cmd
memiliki spasi dalam outputnya, yang pertama akan gagal.xargs gagal dengan backslash, tanda kutip. Itu perlu sesuatu seperti
Opsi xargs -0:
ls -1
menghentikan item dengan karakter baris baru, jaditr
menerjemahkannya menjadi karakter nol.Pendekatan ini sekitar 50 kali lebih lambat daripada iterasi secara manual dengan
for ...
(lihat jawaban Michael Aaron Safyan ) (3,55s vs 0,066s). Tetapi untuk perintah input lain seperti mencari, menemukan, membaca dari file (tr \\n \\0 <file
) atau sejenisnya, Anda harus bekerja denganxargs
seperti ini.sumber
Hasil yang lebih baik untuk saya:
sumber
find . -mindepth 1 -maxdepth 1 -print0 | xargs -0 command
akan menangani kasus di mana output darils -1
ambigu; gunakan-printf '%P\0'
daripada-print0
jika Anda tidak ingin memimpin./
pada masing-masing.saya suka menggunakan gawk untuk menjalankan banyak perintah pada daftar, misalnya
Namun melarikan diri dari karakter yang lolos bisa menjadi sedikit berbulu.
sumber