14

我正在尝试将字符串拆分为两个变量(无需使用 while 循环):

var="hello:world"
IFS=':' read var1 var2 <<< $var

echo "var1: $var1"
echo "var2: $var2"

但我没有得到想要的结果:

var1: 'hello world'
var2: ''

有人可以解释一下是否可以这样做(或类似的方式)?

4

2 回答 2

24

这是 Bash 4.2 中的一个错误。请参阅chepner 的答案以获得正确的解释。


这是关于报价的。利用:

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=
于 2013-11-22T12:11:39.933 回答
12

仅供未来读者参考:

在与开发人员讨论后,看来这确实是bash4.2 中的一个错误,并已在即将发布的 4.3 版本中修复。从开发分支更改日志

呸呸呸。修复了 IFS 在临时环境中出现并用于重定向时的几个问题。

尽管无论如何引用参数扩展总是一个好主意,但 OP 的代码应该在没有引号的情况下按预期工作。


这是对该错误的解释。用代码

var="hello:world"
IFS=':' read var1 var2 <<< $var

未引用的$var 应该是一个单词,因为它的全局值中不包含任何字符IFS(即没有空格)。read然后应该看到字符串hello:world。因为它接收到两个参数,所以它应该使用其局部值IFS、 产生helloworld分别分配给var1和来应用分词var2

错误是这里的字符串似乎使用IFS传递给的“泄漏”值进行了部分拆分read。结果,字符串变为hello world,但仍被视为read单个单词。由于该单词不包含 a :read因此不会将其拆分为两个单词,并且将整个字符串分配给var1

如文件所述,在bash4.3 中,扩展 of$var不会作为<<<运算符的参数进行分词;编码

var="hello:1:2 world"
IFS=: read var1 var2 <<< $var

设置var1hello和。var2_1:2 world

于 2013-11-23T14:31:13.627 回答