字符串连接不适用于逗号字符

String concatenation doesn't work for comma character

bash 脚本中的字符串连接不适用于逗号“,”字符。

A="Hello";
B=",World";
C=$A$B
echo $C;

它将输出打印为

Hello World

Bash 版本为:

GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)

相同的代码似乎在 here

中有效

最可能的解释是您将 $IFS 设置为 ,

最简单的解决方法是 双引号 $C,在这种情况下 echo传递值 unmodified:

echo "$C"

另请注意,您不需要分号来终止命令,因为每个命令都在其自己的行上。


以明确的形式打印$IFS的当前值,请使用

printf '%q\n' "$IFS"  # the default value will print as $' \t\n' - space, tab, newline

至于为什么,消失了

  • 当您使用 未加引号的 变量引用时,例如 $C,shell 将各种 shell expansions 应用于该值。
  • 值得注意的是,应用了单词拆分,这意味着使用特殊 $IFS 变量中包含的任何字符作为分隔符将值拆分为标记( "IFS"代表"Internal Field Separator").
  • 默认情况下,$IFS 包含一个 space、一个制表符和一个换行符,有效地按 whitespace.
  • 在您的情况下,$IFS 可能包含 ,,导致 Hello,World 分裂为 HelloWorld,然后传递给 echo 作为单独的参数。如前所述,双引号变量引用可防止此行为。
  • echo,当给定多个参数时,总是使用单个space在输出时将它们分开.

设置提示$IFS:

由于 $IFS 是一个全局变量最好在更改后将其恢复到以前的值

prevIFS=$IFS IFS=',' # save old value, set desired value (',', in this example)
# ... perform operations with custom $IFS in effect
IFS=$prevIFS         # restore old value

但是,有技术可以本地化更改,这意味着您不必显式保存和恢复其先前的值:


如果自定义 $IFS 值仅用于基于外部实用程序或内置的 单个命令 -- 通常 read -- IFS=... 添加到命令 之前;例如:

IFS=/ read -r var1 var2 <<<'a/b'  # -> $var1 == 'a', $var2 == 'b'

这使得更改的 $IFS 生效 对调用的命令。

警告:这在更改的 IFS 值必须在调用内置/可执行文件之前生效的情况下不起作用,例如 shell 扩展;例如:

 # !! Does NOT work as intended, because $var is expanded BEFORE `IFS=/` takes effect.
var='a/b'; IFS=/ set -- $var

在shell函数中,如果你想改变$IFS整个[=122] =] 函数,但 用于该函数 使用 local $IFS 变量 阴影 全局 $IFS:

foo() {
    local IFS=/ var1 var2 # $IFS change confined to this function due to `local`
    read -r  var1 var2 <<<""
    echo "[$var1] [$var2]"
 }

 foo "a/b" # -> '[a] [b]'

如果可行,subshell:

中附上命令列表
(arr=(a b); IFS=/; echo "${arr[*]}") # -> 'a/b'

$IFS修改只对subshell可见。

警告:在子shell中修改或创建的变量对当前shell可见(事实上​​,这正是这项技术所依赖的)。