将定界字符串解析为 Bash 中的数组 - 为什么“$var”与 $var 不同,尽管 $var 没有空格?
Parsing a delimited string into an array in Bash - why is "$var" different from $var though $var has no spaces?
我是运行Bash版本4.2.25。这是我的代码:
#!/usr/bin/env bash
string="one:two:three:four"
# without quotes
IFS=: read -ra array_1 <<< $string
for i in "${array_1[@]}"; do printf "i = [$i]\n"; done
# output:
# i = [one two three four]
# with quotes
IFS=: read -ra array_2 <<< "$string"
for i in "${array_2[@]}"; do printf "i = [$i]\n"; done
# output:
# i = [one]
# i = [two]
# i = [three]
# i = [four]
如何解释行为差异?
它看起来像一个错误。我回顾了 CHANGES
and couldn't find anything specific, but on cygwin bash 4.3.48(8), both quoted and unquoted give the expected output (four lines). Sometime when I have bandwidth to burn I'll clone the repo and blame redir.c 以查看是否可以找到一些相关的提交。
我无法在 Linux 使用 bash 4.2.46 和 bash 4.3.30 重现您的问题。然而,这里有一个改编版本,确实显示了所描述的行为:
string="one:two:three:four"
IFS=:
read -ra array_1 <<< $string
for i in "${array_1[@]}"; do printf "i = [$i]\n"; done
# i = [one two three four]
read -ra array_2 <<< "$string"
for i in "${array_2[@]}"; do printf "i = [$i]\n"; done
# i = [one]
# i = [two]
# i = [three]
# i = [four]
发生这种情况是因为变量实际上并未在 space 上拆分,它们在 $IFS
上拆分(默认为 space、制表符和换行符)。
因为我们已经覆盖了 $IFS
,它是带有冒号的值,我们必须小心引用。空格不再重要。
源码显示Bashhardcodes a space in string_list
, called through write_here_string。当 IFS
不包含 space 时,扩展为多个单词的字符串将不再 read
变成类似行的标记,从而使差异更加明显。
PS:这是一个很好的例子,说明为什么我们应该始终引用我们的变量,即使我们知道它们包含什么。
我是运行Bash版本4.2.25。这是我的代码:
#!/usr/bin/env bash
string="one:two:three:four"
# without quotes
IFS=: read -ra array_1 <<< $string
for i in "${array_1[@]}"; do printf "i = [$i]\n"; done
# output:
# i = [one two three four]
# with quotes
IFS=: read -ra array_2 <<< "$string"
for i in "${array_2[@]}"; do printf "i = [$i]\n"; done
# output:
# i = [one]
# i = [two]
# i = [three]
# i = [four]
如何解释行为差异?
它看起来像一个错误。我回顾了 CHANGES
and couldn't find anything specific, but on cygwin bash 4.3.48(8), both quoted and unquoted give the expected output (four lines). Sometime when I have bandwidth to burn I'll clone the repo and blame redir.c 以查看是否可以找到一些相关的提交。
我无法在 Linux 使用 bash 4.2.46 和 bash 4.3.30 重现您的问题。然而,这里有一个改编版本,确实显示了所描述的行为:
string="one:two:three:four"
IFS=:
read -ra array_1 <<< $string
for i in "${array_1[@]}"; do printf "i = [$i]\n"; done
# i = [one two three four]
read -ra array_2 <<< "$string"
for i in "${array_2[@]}"; do printf "i = [$i]\n"; done
# i = [one]
# i = [two]
# i = [three]
# i = [four]
发生这种情况是因为变量实际上并未在 space 上拆分,它们在 $IFS
上拆分(默认为 space、制表符和换行符)。
因为我们已经覆盖了 $IFS
,它是带有冒号的值,我们必须小心引用。空格不再重要。
源码显示Bashhardcodes a space in string_list
, called through write_here_string。当 IFS
不包含 space 时,扩展为多个单词的字符串将不再 read
变成类似行的标记,从而使差异更加明显。
PS:这是一个很好的例子,说明为什么我们应该始终引用我们的变量,即使我们知道它们包含什么。