Saya memiliki file teks yang berisi satu nama file di setiap baris:
111_c4l5r120.png
123_c4l4r60.png
135_c4l4r180.png
147_c4l3r60.png
15_c4l1r120.png
...
Saya ingin mengubahnya dalam bentuk ini:
111_c4l5r120.png 111
123_c4l4r60.png 123
135_c4l4r180.png 135
147_c4l3r60.png 147
15_c4l1r120.png 15
...
menggunakan kode ini:
#!/bin/bash
while IFS='' read -r line || [[ -n "$line" ]]; do
echo "$line" >> output.txt
echo "$line" | cut -d'_' -f 1 >> output.txt
done < "$1"
tetapi, hasilnya adalah:
111_c4l5r120.png
111
123_c4l4r60.png
123
135_c4l4r180.png
135
147_c4l3r60.png
147
15_c4l1r120.png
15
...
Bagaimana saya harus mengubah skrip saya untuk mendapatkan hasil keinginan?
shell
shell-script
Ali
sumber
sumber
Jawaban:
Kecuali Anda memiliki kebutuhan khusus untuk menggunakan shell untuk ini, jawaban terdon memberikan alternatif yang lebih baik.
Karena Anda menggunakan
bash
(seperti yang ditunjukkan dalam shebang skrip), Anda dapat menggunakan-n
opsi untuk menggema:Atau Anda dapat menggunakan fitur shell untuk memproses baris tanpa menggunakan
cut
:(mengganti kedua
echo
baris).Atau,
printf
akan melakukan trik juga, bekerja di shell POSIX , dan umumnya lebih baik (lihat Mengapa printf lebih baik daripada gema? Untuk detail):atau
(Sebenarnya, di dataran
/bin/sh
,echo -n
tidak portabel . Karena Anda secara eksplisit menggunakannyabash
tidak masalah di sini.)sumber
Jangan lakukan hal semacam ini di shell! Itu jauh lebih kompleks dari yang diperlukan, rawan kesalahan dan jauh, jauh, lebih lambat. Ada banyak alat yang dirancang untuk manipulasi teks seperti itu. Misalnya, dalam
sed
( di sini mengasumsikan implementasi GNU atau BSD terbaru untuk-E
):Atau, untuk apa saja
sed
:Perl:
awk:
sumber
sed
menjadised 's/\([^_]*\).*/& \1/' file
portabilitas ekstra. Intinya adalah, Anda dapat mengandalkanawk
dansed
berada di sana lebih dari yang dapat Anda andalkan cukup banyak hal lain.Anda disini:
Keluaran:
sumber