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

Raj*_*ani 2 bash string-concatenation

bash脚本上的字符串连接对逗号","字符不起作用.

A="Hello";
B=",World";
C=$A$B
echo $C;
Run Code Online (Sandbox Code Playgroud)

它将输出打印为

你好,世界

Bash版本是:

GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
Run Code Online (Sandbox Code Playgroud)

相同的代码似乎在这里工作

mkl*_*nt0 8

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

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

echo "$C"
Run Code Online (Sandbox Code Playgroud)

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


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

printf '%q\n' "$IFS"  # the default value will print as $' \t\n' - space, tab, newline
Run Code Online (Sandbox Code Playgroud)

至于为什么,消失了:

  • 当您使用不带引号的变量引用时$C,shell会对值应用各种shell扩展.
  • 值得注意的是,应用了单词分割,这意味着使用特殊$IFS变量中包含的任何字符作为分隔符将值拆分为标记("IFS"代表"内部字段分隔符").
  • 默认情况下,$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
Run Code Online (Sandbox Code Playgroud)

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


如果$IFS基于外部实用程序或内置命令单个命令需要自定义值- 通常read- IFS=...置于命令 ; 例如:

IFS=/ read -r var1 var2 <<<'a/b'  # -> $var1 == 'a', $var2 == 'b'
Run Code Online (Sandbox Code Playgroud)

这使更改仅对调用的命令$IFS生效.

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

 # !! Does NOT work as intended, because $var is expanded BEFORE `IFS=/` takes effect.
var='a/b'; IFS=/ set -- $var
Run Code Online (Sandbox Code Playgroud)

内壳的功能,如果你想改变$IFS功能,但针对功能,使用局部 $IFS变量阴影的全球$IFS:

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]'
Run Code Online (Sandbox Code Playgroud)

如果可行,请子shell中包含命令列表:

(arr=(a b); IFS=/; echo "${arr[*]}") # -> 'a/b'
Run Code Online (Sandbox Code Playgroud)

$IFS修改是唯一可见的子shell.

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

  • @TomFenech:`IFS = $'\ t \n'` (3认同)
  • 感谢您快速回复@ mklement0.它工作正常,一旦完成它,我将IFS值重置为旧状态 (2认同)