字符串连接不适用于逗号字符
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
分裂为 Hello
和 World
,然后传递给 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可见(事实上,这正是这项技术所依赖的)。
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
分裂为Hello
和World
,然后传递给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可见(事实上,这正是这项技术所依赖的)。