Di versi lama bash
Anda harus mengutip variabel setelahnya <<<
. Itu diperbaiki di 4.4. Dalam versi yang lebih lama, variabel akan dipecah pada IFS dan kata-kata yang dihasilkan bergabung di ruang sebelum disimpan dalam file sementara yang membentuk <<<
pengalihan itu.
Di 4.2 dan sebelumnya, ketika mengarahkan ulang builtin seperti read
atau command
, pemisahan itu bahkan akan mengambil IFS untuk builtin itu (4.3 memperbaiki itu):
$ bash-4.2 -c 'a=a.b.c.d; IFS=. read x <<< $a; echo "$x"'
a b c d
$ bash-4.2 -c 'a=a.b.c.d; IFS=. cat <<< $a'
a.b.c.d
$ bash-4.2 -c 'a=a.b.c.d; IFS=. command cat <<< $a'
a b c d
Yang diperbaiki di 4.3:
$ bash-4.3 -c 'a=a.b.c.d; IFS=. read x <<< $a; echo "$x"'
a.b.c.d
Namun $a
masih ada pemisahan kata di sana:
$ bash-4.3 -c 'a=a.b.c.d; IFS=.; read x <<< $a; echo "$x"'
a b c d
Dalam 4.4:
$ bash-4.4 -c 'a=a.b.c.d; IFS=.; read x <<< $a; echo "$x"'
a.b.c.d
Untuk portabilitas ke versi yang lebih lama, kutip variabel Anda (atau gunakan dari zsh
mana <<<
asalnya dan yang tidak memiliki masalah itu)
$ bash-any-version -c 'a=a.b.c.d; IFS=.; read x <<< "$a"; echo "$x"'
a.b.c.d
Perhatikan bahwa pendekatan untuk memecah string hanya berfungsi untuk string yang tidak mengandung karakter baris baru. Juga mencatat bahwa a..b.c.
akan terpecah menjadi "a"
, ""
, "b"
, "c"
(tidak ada mengosongkan elemen terakhir).
Untuk membagi string sewenang-wenang, Anda dapat menggunakan operator split + glob sebagai gantinya (yang akan menjadikannya standar dan menghindari menyimpan konten variabel dalam file temp seperti <<<
halnya):
var='a.new
line..b.c.'
set -o noglob # disable glob
IFS=.
set -- $var'' # split+glob
for i do
printf 'item: <%s>\n' "$i"
done
atau:
array=($var'') # in shells with array support
The ''
adalah untuk melestarikan elemen kosong tertinggal jika ada. Itu juga akan membagi kosong $var
menjadi satu elemen kosong.
Atau gunakan shell dengan operator pemisahan yang tepat:
zsh
:
array=(${(s:.:)var} # removes empty elements
array=("${(@s:.:)var}") # preserves empty elements
rc
:
array = ``(.){printf %s $var} # removes empty elements
fish
set array (string split . -- $var) # not for multiline $var