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:
- 当您使用未加引号的变量引用(例如 $ C )时,shell将应用各种 shell展开到该值.
- 值得注意的是,应用了 word splitting ,这意味着该值使用特殊的 $ IFS 变量中包含的任何字符作为分隔符("IFS"代表内部字段分隔符".
- 默认情况下, $ IFS 包含一个空格,一个制表符和一个换行符,有效地由 whitespace 分隔.
- 在您的情况下, $ IFS 可能包含,导致 Hello,World 分为 Hello 和 World ,然后作为单独的参数传递给 echo .如前所述,双引号变量引用可以防止这种情况.
- echo ,当给定多个参数时,总是使用单个空格在输出中将它们分开.
- 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]'如果可行,请将命令列表放在 subshell 中:
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).
更多推荐
字符串连接不适用于逗号字符
发布评论