Masalahnya bukan di cat
, maupun di for
lingkaran itu sendiri; itu dalam penggunaan tanda kutip kembali. Saat Anda menulis:
for i in `cat file`
atau (lebih baik):
for i in $(cat file)
atau (dalam bash
):
for i in $(<file)
shell mengeksekusi perintah dan menangkap output sebagai string, memisahkan kata-kata pada karakter di $IFS
. Jika Anda ingin memasukkan baris ke $i
, Anda juga harus mengutak-atik IFS
atau gunakan while
lingkaran. while
loop lebih baik jika ada bahaya bahwa file yang diproses akan berukuran besar; tidak harus membaca seluruh file ke dalam memori sekaligus, tidak seperti versi yang menggunakan $(...)
.
IFS='
'
for i in $(<file)
do echo "$i"
done
Kutipan di sekitar "$i"
umumnya adalah ide yang bagus. Dalam konteks ini, dengan $IFS
yang dimodifikasi , sebenarnya tidak kritis, tapi kebiasaan baik tetaplah kebiasaan baik. Itu penting dalam skrip berikut:
old="$IFS"
IFS='
'
for i in $(<file)
do
(
IFS="$old"
echo "$i"
)
done
ketika file data berisi banyak spasi di antara kata-kata:
$ cat file
abc 123, comma
the quick brown fox
jumped over the lazy dog
comma, comma
$
Keluaran:
$ sh bq.sh
abc 123, comma
the quick brown fox
jumped over the lazy dog
comma, comma
$
Tanpa tanda kutip ganda:
$ cat bq.sh
old="$IFS"
IFS='
'
for i in $(<file)
do
(
IFS="$old"
echo $i
)
done
$ sh bq.sh
abc 123, comma
the quick brown fox
jumped over the lazy dog
comma, comma
$
Anda dapat menggunakan IFS
variabel ke spesifik Anda menginginkan baris baru sebagai pemisah bidang:
IFS=$'\n'
for i in `cat file`
do
echo $i
done
loop for yang digabungkan dengan perubahan pemisah bidang internal (IFS) akan membaca file sebagaimana dimaksud
untuk masukan
abc 123, comma
the quick brown fox
jumped over the lazy dog
comma, comma
For loop digabungkan dengan perubahan IFS
old_IFS=$IFS
IFS=$'\n'
for i in `cat file`
do
echo $i
done
IFS=$old_IFS
menghasilkan
abc 123, comma
the quick brown fox
jumped over the lazy dog
comma, comma