我正在尝试将字符串拆分为两个变量(不必使用while循环):
var="hello:world"
IFS=':' read var1 var2 <<< $var
echo "var1: $var1"
echo "var2: $var2"
但我没有得到理想的结果:
var1: 'hello world'
var2: ''
有人可以解释一下是否可以这样做(或类似方式)?
答案 0 :(得分:21)
这是关于报价。使用:
IFS=':' read var1 var2 <<< "$var"
^ ^
而不是
IFS=':' read var1 var2 <<< $var
见结果:
$ IFS=':' read var1 var2 <<< "$var"
$ echo "var1=$var1, var2=$var2"
var1=hello, var2=world
但是
$ IFS=':' read var1 var2 <<< $var
$ echo "var1=$var1, var2=$var2"
var1=hello world, var2=
答案 1 :(得分:11)
未来读者的费用:
在与开发人员讨论之后,看来这确实是bash
4.2中的一个错误,并且已经在即将发布的4.3版本中得到修复。来自devel branch change log
RRRR。修复了IFS在临时环境中出现时的几个问题 并用于重定向。
尽管引用参数扩展总是一个好主意,但是OP的代码应该按预期工作而没有引号。
以下是该错误的解释。使用代码
var="hello:world"
IFS=':' read var1 var2 <<< $var
未加引号的$var
应该是一个单词,因为它在IFS
的全局值中不包含任何字符(即,没有空格)。然后read
会看到字符串hello:world
。由于它收到两个参数,因此应使用其IFS
的本地值应用分词,生成分配给hello
和world
的{{1}}和var1
分别。
该错误是,此处字符串似乎使用var2
传递给IFS
的“泄露”值进行部分拆分。结果,字符串变为read
,但仍被hello world
视为单个字。由于该字词不包含read
,:
不会将其拆分为两个字,而整个字符串都会分配给read
。
在var1
4.3中,如文档所述,bash
的扩展不会将字拆分作为$var
运算符的参数;代码
<<<
将var="hello:1:2 world"
IFS=: read var1 var2 <<< $var
设为var1
,将hello
设为var2
。