字符串连接不适用于逗号字符 [英] String concatenation doesn't work for comma character

查看:40
本文介绍了字符串连接不适用于逗号字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

bash脚本上的字符串连接不适用于逗号,"字符.

String concatenation on bash script doesn't work on comma "," character.

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

将输出打印为

Hello World

Hello World

bash版本为:

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

相同的代码似乎可以在此处

The same code seems to work in here

推荐答案

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

The most likely explanation is that you have $IFS set to ,

解决此问题的最简单方法是 双引号 $ C ,在这种情况下,将传递 echo 未修改:

The simplest way around this is to double-quote $C, in which case echo is passed the value unmodified:

echo "$C"

还请注意,由于每个命令都在其单独的行上,因此您不需要分号来终止命令.

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

To print the current value of $IFS in unambiguous form, use

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


关于为什么消失:


As for why the , disappeared:

  • When you use an unquoted variable reference such as $C, the shell applies various shell expansions to the value.
  • Notably, word splitting is applied, which means that the value is split into tokens using any of the characters contained in the special $IFS variable as a separator ("IFS" stands for "Internal Field Separator").
  • By default, $IFS contains a space, a tab, and a newline, effectively splitting by whitespace.
  • In your case, $IFS likely contained , resulting in Hello,World getting split into Hello and World, which are then passed to echo as separate arguments. As stated, double-quoting variable references prevents this behavior.
  • echo, when given multiple arguments, always uses a single space to separate them on output.

设置 $ IFS 的提示:

Tips for setting $IFS:

由于 $ IFS 是全局变量,因此在更改后将其恢复为以前的值是一种很好的做法:

Since $IFS is a global variable, it's good practice to restore it to its previous value after changing it:

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

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

However, there are techniques that localize the change, which means you do not have to explicitly save and restore its previous value:

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

If a custom $IFS value is only needed for a single command based on an external utility or builtin -- typically read -- prepend IFS=... to the command; e.g.:

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

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

This makes the changed $IFS take effect only for the command invoked.

注意事项:这在更改的IFS值必须在调用内置程序/可执行文件之前必须生效的情况下不起作用,例如使用Shell扩展;例如:

Caveat: This does NOT work in situations where the changed IFS value must take effect BEFORE invoking the builtin / executable, such as with shell expansions; e.g.:

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


如果要整个功能更改 $ IFS ,但仅 该功能使用本地 $ IFS 变量,该变量遮盖全局<代码> $ IFS :


Inside a shell function, if you want to change $IFS for the entire function, but only for that function, use a local $IFS variable that shadows the global $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]'


如果可行,请将命令列表放在 subshel​​l 中:


If feasible, enclose a list of commands in a subshell:

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

$ IFS 修改仅对子外壳可见.

The $IFS modification is only visible to subshell.

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

Caveat: variables modified or created in the subshell are not visible to the current shell (which is, in fact, what this technique relies on).

这篇关于字符串连接不适用于逗号字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆