【问题标题】:Prevent IFS to stop on new lines防止 IFS 在新行上停止
【发布时间】:2014-08-19 14:05:52
【问题描述】:

我有一个多行字符串,我想使用单个分隔符 | 将其转换为数组。但是,当设置IFS=| 时,它将在新行出现之前停止:

IFS='|' read -a VARS <<< "var1|var2|var3
                          var4|var5|var6
                          var7|var8|var9"

echo ${VARS[@]}
#output => var1 var2 var3

我想知道为什么不会评估剩余的行以及如何防止这种情况发生,能够分配每个变量而不管是否存在新行?

【问题讨论】:

  • IFS 仅用于拆分单个字符串中的字段。 read 一次只能读取一行。您的此处字符串由 行组成。

标签: bash shell unix ifs


【解决方案1】:

将您的IFS 设置为|\n 并使用-d 来使用除换行符之外的另一个分隔符。你还需要保持你的价值观不变。空格也可以包含在内。

IFS=$'|\n' read -d '' -a VARS <<< "var1|var2|var3
var4|var5|var6
var7|var8|var9"

read 默认只读取第一个换行符,除非被-d 更改。 '' 也是 $'\0' 的同义词,作为它的参数。

还有一点

双引号内的空格(包括换行符)不会被忽略。它们也包含在字面上作为一个值。

所以也许你真正应该做的是:

IFS='|' read -a VARS <<< "var1|var2|var3|var4|var5|var6|var7|var8|var9"

【讨论】:

  • 这是很棒的 konsolebox。谢谢你。任何想法为什么IFS='|' read -a VARS &lt;&lt;&lt; `echo var1|var2|var3` 不会产生相同的效果(因为它是命令的输出?
  • @zanona 如果你没有引用echo var1|var2|var3| 将被解释为一个简单命令的管道。
  • 谢谢@konsolebox,只要弄清楚什么时候是命令输出我应该使用&lt; &lt;(command) 而不是&lt;&lt;&lt;`command` 现在可以使用
【解决方案2】:

在 bash 中,编写多行字符串的正确语法如下:

IFS='|' read -a VARS <<< "var1|var2|var3 \
                          var4|var5|var6 \
                          var7|var8|var9"
echo ${VARS[@]}
#>var1 var2 var3 var4 var5 var6 var7 var8 var9

#However, you will have
echo "${VARS[@]}"
#>var1 var2 var3                           var4 var5 var6                           var7 var8 var9

如果您想将字符串写成多行字符串并完全删除空格,您可以将| 添加到现有的$IFS 而不是删除它

IFS=$IFS'|' read -a VARS <<< "var1|var2|var3 \
                              var4|var5|var6 \
                              var7|var8|var9"
echo "${VARS[@]}"
#>var1 var2 var3 var4 var5 var6 var7 var8 var9

【讨论】:

  • 我真的不知道用 `` 换行,非常感谢 Plotoux 的提示
  • @zanona 没问题,很高兴它有帮助 ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-29
  • 1970-01-01
  • 1970-01-01
  • 2019-08-09
  • 1970-01-01
相关资源
最近更新 更多