Trong các phiên bản cũ của bash
bạn đã phải trích dẫn các biến sau <<<
. Điều đó đã được sửa trong 4.4. Trong các phiên bản cũ hơn, biến sẽ được phân tách trên IFS và các từ kết quả được nối trên không gian trước khi được lưu trữ trong tệp tạm thời tạo nên sự <<<
chuyển hướng đó .
Trong 4.2 trở về trước, khi chuyển hướng các nội dung như read
hoặc command
, việc chia tách đó thậm chí sẽ lấy IFS cho nội dung đó (4.3 đã sửa lỗi đó):
$ 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
Cái đó đã được sửa trong 4.3:
$ bash-4.3 -c 'a=a.b.c.d; IFS=. read x <<< $a; echo "$x"'
a.b.c.d
Nhưng $a
vẫn phải chịu sự chia tách từ đó:
$ bash-4.3 -c 'a=a.b.c.d; IFS=.; read x <<< $a; echo "$x"'
a b c d
Trong 4,4:
$ bash-4.4 -c 'a=a.b.c.d; IFS=.; read x <<< $a; echo "$x"'
a.b.c.d
Đối với tính di động đối với các phiên bản cũ hơn, hãy trích dẫn biến của bạn (hoặc sử dụng từ zsh
đâu <<<
đến từ nơi đầu tiên và điều đó không có vấn đề đó)
$ bash-any-version -c 'a=a.b.c.d; IFS=.; read x <<< "$a"; echo "$x"'
a.b.c.d
Lưu ý rằng cách tiếp cận để phân tách một chuỗi chỉ hoạt động đối với các chuỗi không chứa các ký tự dòng mới. Cũng lưu ý rằng a..b.c.
sẽ chia thành "a"
, ""
, "b"
, "c"
(không có sản phẩm nào yếu tố cuối cùng).
Để phân tách các chuỗi tùy ý, bạn có thể sử dụng toán tử split + global thay thế (điều này sẽ làm cho nó trở thành tiêu chuẩn và tránh lưu trữ nội dung của một biến trong tệp tạm thời như sau <<<
):
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
hoặc là:
array=($var'') # in shells with array support
Đây ''
là để bảo tồn một yếu tố trống rỗng nếu có. Điều đó cũng sẽ chia một phần trống $var
thành một phần tử trống.
Hoặc sử dụng shell với toán tử tách thích hợp:
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