试图将字符串拆分为两个变量

cod*_*oda 13 bash shell ifs

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

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

echo "var1: $var1"
echo "var2: $var2"
Run Code Online (Sandbox Code Playgroud)

但我没有得到预期的结果:

var1: 'hello world'
var2: ''
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释是否可以这样做(或类似的方式)?

fed*_*qui 21

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


这是关于报价.使用:

IFS=':' read var1 var2 <<< "$var"
                           ^    ^
Run Code Online (Sandbox Code Playgroud)

代替

IFS=':' read var1 var2 <<< $var
Run Code Online (Sandbox Code Playgroud)

看结果:

$ IFS=':' read var1 var2 <<< "$var"
$ echo "var1=$var1, var2=$var2"
var1=hello, var2=world
Run Code Online (Sandbox Code Playgroud)

$ IFS=':' read var1 var2 <<< $var
$ echo "var1=$var1, var2=$var2"
var1=hello world, var2=
Run Code Online (Sandbox Code Playgroud)

  • @chepner我发现了另一个有趣的行为:如果你做`IFS =':'读var1 var2 <<< hello:bye`然后它会正确拆分,而如果它来自变量则不然. (2认同)
  • 当然.是的,`<< EOF $ varEOF`(预期位置中的换行符)与此处引用的字符串相同.错误是通过电子邮件报告的,因此没有链接到错误跟踪器(尚未). (2认同)

che*_*ner 11

未来读者的供参考:

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

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

尽管引用参数扩展总是一个好主意,但是OP的代码应该按预期工作而不带引号.


这是对错误的解释.随着代码

var="hello:world"
IFS=':' read var1 var2 <<< $var
Run Code Online (Sandbox Code Playgroud)

unquoted $var 应该是一个单词,因为它在全局值中没有包含字符IFS(即没有空格).read然后应该看到字符串hello:world.因为它接收到两个参数,所以它应该使用其本地值IFS,生成helloworld分别分配给var1和应用var2分词.

错误是这里的字符串似乎使用IFS传递给的"泄露"值进行部分拆分read.结果,字符串变为hello world,但仍然被read看作一个单词.由于该单词不包含a :,因此read不会将其拆分为两个单词,并将整个字符串赋值给var1.

bash4.3中,如文档所述,扩展$var不会将字拆分作为<<<运算符的参数; 代码

var="hello:1:2 world"
IFS=: read var1 var2 <<< $var
Run Code Online (Sandbox Code Playgroud)

设置var1hellovar21:2 world.