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

时间:2015-04-07 13:56:19

标签: bash string-concatenation

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

1 个答案:

答案 0 :(得分:7)

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

最简单的方法是 双引号 $C ,在这种情况下echo传递值未修改< / EM>:

echo "$C"

另请注意,鉴于每个命令都在自己的行上,您不需要使用分号来终止命令。


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

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

至于为什么,消失

  • 当您使用未加引号的变量引用(例如$C)时,shell会将各种shell expansions应用于该值。
  • 值得注意的是,应用分词,这意味着使用特殊$IFS变量中包含的任何字符作为分隔符将值拆分为标记(&#34; IFS& #34;代表&#34;内部字段分隔符&#34;)。
  • 默认情况下,$IFS包含空格,制表符和换行符,可以通过空格进行有效分割。
  • 在您的情况下,$IFS可能包含,,导致Hello,World被分为HelloWorld,然后传递给echo } 作为单独的参数。如上所述,双引号变量引用可防止此行为。
  • echo,当给出多个参数时,始终使用单个空格在输出中将它们分开。

设置$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 - prepend {{1命令; e.g:

IFS=...

这使得已更改的IFS=/ read -r var1 var2 <<<'a/b' # -> $var1 == 'a', $var2 == 'b' 仅对生效。

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

$IFS

在shell 功能中,如果您想更改整个功能的 # !! Does NOT work as intended, because $var is expanded BEFORE `IFS=/` takes effect. var='a/b'; IFS=/ set -- $var ,而该功能使用本地 $IFS变量 阴影全局$IFS

$IFS

如果可行,将一个命令列表包含在子shell 中:

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

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

(arr=(a b); IFS=/; echo "${arr[*]}") # -> 'a/b' 修改仅对子shell可见。

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