Saya mungkin memiliki sesuatu yang benar-benar salah, tetapi terlihat meyakinkan bagi saya, bahwa menetapkan IFS sebagai salah satu perintah dalam daftar pra-lakukan / selesai sama sekali tidak berpengaruh.
IFS luar (di luar while
konstruk) berlaku dalam semua contoh yang ditunjukkan dalam skrip di bawah ini ..
Apa yang terjadi di sini? Apakah saya mendapat ide yang salah tentang apa yang dilakukan IFS dalam situasi ini? Saya mengharapkan hasil array-split seperti yang ditunjukkan pada kolom "diharapkan".
#!/bin/bash
xifs() { echo -n "$(echo -n "$IFS" | xxd -p)"; } # allow for null $IFS
show() { x=($1)
echo -ne " (${#x[@]})\t |"
for ((j=0;j<${#x[@]};j++)); do
echo -n "${x[j]}|"
done
echo -ne "\t"
xifs "$IFS"; echo
}
data="a b c"
echo -e "----- -- -- \t --------\tactual"
echo -e "outside \t IFS \tinside"
echo -e "loop \t Field \tloop"
echo -e "IFS NR NF \t Split \tIFS (actual)"
echo -e "----- -- -- \t --------\t-----"
IFS=$' \t\n'; xifs "$IFS"; echo "$data" | while read; do echo -ne '\t 1'; show "$REPLY"; done
IFS=$' \t\n'; xifs "$IFS"; echo "$data" | while IFS= read; do echo -ne '\t 2'; show "$REPLY"; done
IFS=$' \t\n'; xifs "$IFS"; echo "$data" | while IFS=b read; do echo -ne '\t 3'; show "$REPLY"; done
IFS=" "; xifs "$IFS"; echo "$data" | while read; do echo -ne '\t 4'; show "$REPLY"; done
IFS=" "; xifs "$IFS"; echo "$data" | while IFS= read; do echo -ne '\t 5'; show "$REPLY"; done
IFS=" "; xifs "$IFS"; echo "$data" | while IFS=b read; do echo -ne '\t 6'; show "$REPLY"; done
IFS=; xifs "$IFS"; echo "$data" | while read; do echo -ne '\t 7'; show "$REPLY"; done
IFS=; xifs "$IFS"; echo "$data" | while IFS=" " read; do echo -ne '\t 8'; show "$REPLY"; done
IFS=; xifs "$IFS"; echo "$data" | while IFS=b read; do echo -ne '\t 9'; show "$REPLY"; done
IFS=b; xifs "$IFS"; echo "$data" | while IFS= read; do echo -ne '\t10'; show "$REPLY"; done
IFS=b; xifs "$IFS"; echo "$data" | while IFS=" " read; do echo -ne '\t11'; show "$REPLY"; done
echo -e "----- -- -- \t --------\t-----"
Keluaran:
----- -- -- -------- actual
outside IFS inside assigned
loop Field loop # inner
IFS NR NF Split IFS # expected IFS
----- -- -- -------- ----- # --------- --------
20090a 1 (3) |a|b|c| 20090a #
20090a 2 (3) |a|b|c| 20090a # |a b c| IFS=
20090a 3 (3) |a|b|c| 20090a # |a | c| IFS=b
20 4 (3) |a|b|c| 20 #
20 5 (3) |a|b|c| 20 # |a b c IFS=
20 6 (3) |a|b|c| 20 # |a | c| IFS=b
7 (1) |a b c| #
8 (1) |a b c| # |a|b|c| IFS=" "
9 (1) |a b c| # |a | c| IFS=b
62 10 (2) |a | c| 62 # |a b c| IFS=
62 11 (2) |a | c| 62 # |a|b|c| IFS=" "
----- -- -- -------- ----- --------- -------
$IFS
dihilangkan pada awal / akhir baris input, saya kira? (Begitulah cara kerjanya.)a<tab>b
ke dalamread var
akan menghasilkan var memiliki nilaia<space>b
, tetapi jika sebaliknya Anda milikiIFS='<newline>' read var
maka nilai var akan menjadia<tab>b
.Sederhananya, Anda harus membaca lebih dari satu variabel pada suatu waktu agar
IFS=<something> read ...
konstruk memiliki efek yang terlihat dalam contoh Anda 1 .Anda melewatkan ruang lingkup
read
dalam contoh. Tidak ada modifikasi IFS di dalam loop dalam kasus uji Anda. Izinkan saya menunjukkan dengan tepat, di mana IFS kedua memiliki efek di setiap baris Anda:Sama seperti program apa pun yang dijalankan di shell. Variabel yang Anda (re) tentukan di baris perintah memengaruhi eksekusi program. Dan hanya itu (karena Anda tidak mengekspor). Oleh karena itu, untuk menggunakan definisi ulang
IFS
di baris tersebut, Anda harus memintaread
untuk menetapkan nilai ke lebih dari satu variabel . Lihatlah contoh-contoh ini:1 Seperti yang baru saja saya pelajari dari Gilles , sebenarnya mungkin ada manfaat dari pengaturan
IFS=''
(kosong) ketika membaca hanya satu bidang: ia menghindari pemotongan spasi putih di awal baris.sumber
IFS= read
digunakan sebagai preferensi untuk hanya mengatur ulang variabel lingkungan IFS". Saya tidak memiliki kesadaran, kemudian, bahwa variabel lokal dapat ditetapkan oleh pemanggil perintah. Itulah jawaban untuk pertanyaan itu. Itu memang berevolusi lebih jauh untuk mengatasi poin utama pertanyaan ini, tetapi pada saat saya menyadari bahwa, saya sudah mengajukan pertanyaan ini ... Mungkin dua pertanyaan itu sama seperti duased
pertanyaan, jadi perasaan saya untuk menyimpannya sebagai ... Lebih banyak judul untuk googler ke google.