Context | Expression | Result (value of c)
--------------------------------------+-----------------------+---------------------
Two variables | c=$a$b | helloworld
A variable and a literal | c=${a}_world | hello_world
A variable, a literal, with a space | c=${a}" world" | hello world
A more complex expression | c="${a}_one|${b}_2" | hello_one|world_2
Using += operator (Bash 3.1 or later) | c=$a; c+=$b | helloworld
Append literal with += | c=$a; c+=" world" | hello world
28 回答
会输出
当
$blaohai
导致变量未找到错误时,这很有用 . 或者如果字符串中有空格或其他特殊字符 ."${foo}"
正确地逃避你投入的任何东西 .Bash还支持a =运算符,如以下脚本所示:
通常,要连接两个变量,您可以一个接一个地编写它们:
如果它是将
" World"
添加到原始字符串的示例,那么它可以是:输出:
您可以尝试以下方式 . 当替换发生时,双引号将保留空格 .
如果你要做的就是分裂一个将字符串分成几行,可以使用反斜杠:
中间有一个空格:
这个也只增加了一个空格:
即使现在允许=运算符,它也已在2004年的 Bash 3.1 中引入 .
在较旧的Bash版本上使用此运算符的任何脚本都将失败,如果您幸运的话,“找不到命令”错误,或者“意外令牌附近的语法错误” .
对于那些关心向后兼容性的人,请坚持使用旧的标准Bash级联方法,如所选答案中提到的那些:
引号最简单的方法:
如果你想追加下划线之类的东西,请使用escape(\)
这不起作用:
这很好用:
又一种方法......
......还有一个 .
我还不了解PHP,但这适用于Linux Bash . 如果您不想将其影响到变量,可以尝试这样做:
你可以放置另一个变量而不是'Hello'或'!' . 您也可以连接更多字符串 .
我有点像快速功能 .
另一种给猫皮肤的方法 . 这次有功能:D
人们对性能表示担忧,但没有提供数据 . 我建议一个简单的测试 .
(注意:macOS上的
date
不提供纳秒,因此必须在Linux上完成 . )我创建了append_test.sh on GitHub的内容:
测试1:
测试2:
这些错误表明我的Bash在崩溃之前已经达到 335.54432 MB . 您可以将the code更改为将数据加倍以附加常量以获得更精细的图形和故障点 . 但我认为这应该给你足够的信息来决定你是否关心 . 就个人而言,低于100 MB,我没有 . 你的旅费可能会改变 .
首先
Bash
由于这个问题专门针对Bash,我的答案的第一部分将提出不同的方法来正确地做到这一点:
=:附加到变量
语法 += 可以以不同方式使用:
追加到字符串var = ...
(因为我节俭,我只会使用两个变量
foo
和a
,然后在整个答案中重复使用相同的内容 . ;-)使用Stack Overflow问题语法,
工作良好!
附加到整数((var = ...))
变量
a
是一个字符串,但也是一个整数追加到数组var =(...)
我们的
a
也只是一个元素的数组 .请注意,在括号之间,有一个空格分隔的数组 . 如果要在数组中存储包含空格的字符串,则必须将它们括起来:
嗯...... this is not a bug, but a feature ...为了防止bash试图开发
!"
,你可以:printf:使用builtin命令重构变量
printf
builtin命令提供了一种绘制字符串格式的强大方法 . 由于这是一个Bash内置,有一个选项可以将格式化的字符串发送到变量而不是在stdout
上打印:这个数组中有七个字符串 . 所以我们可以构建一个包含七个位置参数的格式化字符串:
或者我们可以使用一个参数格式字符串,该字符串将重复提交多个参数...
请注意,我们的
a
仍然是一个数组!只有第一个元素被改变了!在bash下,当您在不指定索引的情况下访问变量名时,您始终只能查询第一个元素!
所以要检索我们的七个字段数组,我们只需要重新设置第一个元素:
传递给许多参数的一个参数格式字符串:
使用Stack Overflow问题语法:
注意:使用双引号可能对操作包含
spaces
,tabulations
和/或newlines
的字符串很有用壳牌现在
在POSIX shell下,您无法使用bashisms,因此没有内置
printf
.基本上
但你可以这样做:
格式化,使用forked printf
如果你想使用更复杂的结构,你必须使用fork(创建作业的新子进程并通过
stdout
返回结果):从历史上看,您可以使用反引号来检索fork的结果:
但这对于嵌套来说并不容易:
使用反斜杠,你必须用反斜杠逃避内叉:
更安全的方式:
包含空格的字符串可以成为命令的一部分,使用“$ XXX”和“$ ”来避免这些错误 .
再看看关于 += 的其他答案
我方便的时候这样做:使用内联命令!
你也可以这样做:
请注意,这不起作用
因为它似乎放弃了$ foo并离开你:
但这会奏效:
并留下正确的输出:
这是一个通过AWK:
我更喜欢使用大括号
${}
来扩展字符串中的变量:卷曲括号适合连续字符串使用:
否则使用
foo = "$fooWorld"
将无法正常工作 .以下是大多数答案所讨论的简明摘要 .
假设我们有两个变量:
下表解释了我们可以将
a
和b
的值组合在一起以创建新变量c
的不同上下文 .几点说明:
用双引号括起一个赋值的RHS通常是一个好习惯,尽管在许多情况下它是非常可选的
如果以较小的增量构造一个大字符串,尤其是在一个循环中,从性能的角度来看
+=
会更好使用
{}
围绕变量名来消除其扩展的歧义(如上表中的第2行)也可以看看:
BashFAQ/013 - How can I concatenate two variables?
When do we need curly braces around shell variables?
有一个特殊情况需要注意:
将输出
"daniel"san
,而不是danielsan
,就像您可能想要的那样 . 在这种情况下,你应该做:我想从列表中构建一个字符串 . 无法找到答案,所以我在这里发布 . 这是我做的:
然后我得到以下输出:
我解决问题的方法就是
例如,
哪个产生
例如,如果您尝试将字符串与另一个字符串连接起来,
然后
echo "$c"
将产生有一个额外的空间 .
你可能想象不起作用,但是
产生
您可以在没有引号的情况下连接 . 这是一个例子:
最后一个语句将打印“OpenSystems”(没有引号) .
这是Bash脚本的示例: