如何在Bash中连接字符串变量 [英]How to concatenate string variables in Bash

In PHP, strings are concatenated together as follows:

在PHP中,字符串被串联在一起,如下所示:

$foo = "Hello";
$foo .= " World";

Here, $foo becomes "Hello World".

在这里,$foo变成了“Hello World”。

How is this accomplished in Bash?

这是如何在Bash中实现的?

27 个解决方案

#1


2773  

foo="Hello"
foo="$foo World"
echo $foo
> Hello World

In general to concatenate two variables you can just write them one after another:

一般来说,要把两个变量串联起来,你可以把它们一个接一个地写出来:

a='hello'
b='world'
c=$a$b
echo $c
> helloworld

#2


912  

Bash also supports a += operator as shown in the following transcript:

Bash还支持+=操作符,如下文所示:

$ A="X Y"
$ A+="Z"
$ echo "$A"
X YZ

#3


795  

Bash first

As this question stand specifically for Bash, my first part of the answer would present different ways of doing this properly:

由于这个问题是专门针对Bash的,所以我的第一部分回答会给出不同的方法来正确地解决这个问题:

+=: Append to variable

The syntax += may be used in different ways:

语法+=可以有不同的用法:

Append to string var+=...

(Because I am frugal, I will only use two variables foo and a and then re-use the same in the whole answer. ;-)

(因为我很节俭,所以我只使用两个变量foo和a,然后在整个答案中重复使用同一个变量。:-)

a=2
a+=4
echo $a
24

Using the Stack Overflow question syntax,

使用堆栈溢出问题语法,

foo="Hello"
foo+=" World"
echo $foo
Hello World

works fine!

没问题!

Append to an integer ((var+=...))

variable a is a string, but also an integer

变量a是一个字符串,也是一个整数

echo $a
24
((a+=12))
echo $a
36

Append to an array var+=(...)

Our a is also an array of only one element.

a也是一个只有一个元素的数组。

echo ${a[@]}
36

a+=(18)

echo ${a[@]}
36 18
echo ${a[0]}
36
echo ${a[1]}
18

Note that between parentheses, there is a space separated array. If you want to store a string containing spaces in your array, you have to enclose them:

注意,括号之间有一个空格分隔的数组。如果要在数组中存储包含空格的字符串,则必须将其括起来:

a+=(one word "hello world!" )
bash: !": event not found

Hmm.. this is not a bug, but a feature... To prevent bash to try to develop !", you could:

嗯. .这不是一个bug,而是一个特性……为了防止bash尝试开发!

a+=(one word "hello world"! 'hello world!' $'hello world\041')

declare -p a
declare -a a='([0]="36" [1]="18" [2]="one" [3]="word" [4]="hello world!" [5]="h
ello world!" [6]="hello world!")'

printf: Re-construct variable using the builtin command

The printf builtin command gives a powerful way of drawing string format. As this is a Bash builtin, there is a option for sending formated string to a variable instead of printing on stdout:

printf内置命令提供了一种绘制字符串格式的强大方法。由于这是一个Bash构建,所以有一个选项可以将格式化的字符串发送到一个变量,而不是在stdout上打印:

echo ${a[@]}
36 18 one word hello world! hello world! hello world!

There are seven strings in this array. So we could build a formated string containing exactly seven positional arguments:

这个数组中有7个字符串。所以我们可以构建一个包含7个位置参数的格式化字符串:

printf -v a "%s./.%s...'%s' '%s', '%s'=='%s'=='%s'" "${a[@]}"
echo $a
36./.18...'one' 'word', 'hello world!'=='hello world!'=='hello world!'

Or we could use one argument format string wich will be repeated as many argument submited...

或者我们可以使用一个参数格式字符串,当多个参数提交时,它将被重复。

Note that our a is still an array! Only first element is changed!

注意,我们的a仍然是一个数组!只修改了第一个元素!

declare -p a
declare -a a='([0]="36./.18...'\''one'\'' '\''word'\'', '\''hello world!'\''=='\
''hello world!'\''=='\''hello world!'\''" [1]="18" [2]="one" [3]="word" [4]="hel
lo world!" [5]="hello world!" [6]="hello world!")'

Under bash, when you access a variable name without specifying index, you always address first element only!

在bash中,当您访问一个没有指定索引的变量名称时,您总是只处理第一个元素!

So to retrieve our seven field array, we only need to re-set 1st element:

所以要检索我们的七个字段数组,我们只需要重新设置第一个元素:

a=36
declare -p a
declare -a a='([0]="36" [1]="18" [2]="one" [3]="word" [4]="hello world!" [5]="he
llo world!" [6]="hello world!")'

One argument format string with many argument passed to:

一个带多个参数的参数格式字符串传递给:

printf -v a[0] '<%s>\n' "${a[@]}"
echo "$a"
<36>
<18>
<one>
<word>
<hello world!>
<hello world!>
<hello world!>

Using the Stack Overflow question syntax:

foo="Hello"
printf -v foo "%s World" $foo
echo $foo
Hello World

Nota: The use of double-quotes may be useful for manipulating strings that contain spacestabulations and/or newlines

Nota:使用双引号可能对处理包含空格、表格和/或换行的字符串有用

printf -v foo "%s World" "$foo"

Shell now

Under POSIX shell, you could not use bashisms, so there is no builtin printf.

在POSIX shell下,不能使用bashisms,因此不存在内置printf。

Basically

But you could simply do:

但你可以做的很简单:

foo="Hello"
foo="$foo World"
echo $foo
Hello World

Formatted, using forked printf

If you want to use more sophisticated constructions you have to use a fork (new child process that make the job and return the result via stdout):

如果你想使用更复杂的结构,你必须使用一个fork(新的子进程,通过stdout来完成任务并返回结果):

foo="Hello"
foo=$(printf "%s World" "$foo")
echo $foo
Hello World

Historically, you could use backticks for retrieving result of a fork:

从历史上看,您可以使用回勾来检索fork的结果:

foo="Hello"
foo=`printf "%s World" "$foo"`
echo $foo
Hello World

But this is not easy for nesting:

但这对于嵌套来说并不容易:

foo="Today is: "
foo=$(printf "%s %s" "$foo" "$(date)")
echo $foo
Today is: Sun Aug 4 11:58:23 CEST 2013

with backticks, you have to escape inner forks with backslashes:

有了反斜杠,你就必须用反斜杠来避开内叉:

foo="Today is: "
foo=`printf "%s %s" "$foo" "\`date\`"`
echo $foo
Today is: Sun Aug 4 11:59:10 CEST 2013

#4


114  

You can do this too:

你也可以这样做:

$ var="myscript"

$ echo $var

myscript


$ var=${var}.sh

$ echo $var

myscript.sh

#5


99  

bla=hello
laber=kthx
echo "${bla}ohai${laber}bye"

Will output

将输出

helloohaikthxbye

This is useful when $blaohai leads to a variable not found error. Or if you have spaces or other special characters in your strings. "${foo}" properly escapes anything you put into it.

当$blaohai导致变量not found错误时,这很有用。或者如果字符串中有空格或其他特殊字符。“${foo}”正确地转义您放入其中的任何内容。

#6


35  

foo="Hello "
foo="$foo World"

     

     

#7


29  

The way I'd solve the problem is just

我解决这个问题的方法就是

$a$b

For example,

例如,

a="Hello"
b=" World"
c=$a$b
echo "$c"

which produces

生产

Hello World

If you try to concatenate a string with another string, for example,

如果你试图用另一个字符串连接一个字符串,例如,

a="Hello"
c="$a World"

then echo "$c" will produce

然后echo会生成“$c”

Hello World

with an extra space.

额外的空间。

$aWorld

doesn't work, as you may imagine, but

不工作,你可以想象,但是

${a}World

produces

生产

HelloWorld

#8


21  

$ a=hip
$ b=hop
$ ab=$a$b
$ echo $ab
hiphop
$ echo $a$b
hiphop

#9


18  

Yet another approach...

另一个方法…

> H="Hello "
> U="$H""universe."
> echo $U
Hello universe.

...and yet yet another one.

…还有一个。

> H="Hello "
> U=$H"universe."
> echo $U
Hello universe.

#10


18  

If you want to append something like an underscore, use escape (\)

如果您想添加下划线之类的内容,请使用escape (\)

FILEPATH=/opt/myfile

This does not work:

这并不工作:

echo $FILEPATH_$DATEX

This works fine:

这工作正常:

echo $FILEPATH\\_$DATEX

#11


13  

You can concatenate without the quotes. Here is an example:

可以不带引号地连接。这是一个例子:

$Variable1 Open
$Variable2 Systems
$Variable3 $Variable1$Variable2
$echo $Variable3

This last statement would print "OpenSystems" (without quotes).

最后一条语句将打印“OpenSystems”(不带引号)。

This is an example of a Bash script:

这是Bash脚本的一个示例:

v1=hello
v2=world
v3="$v1       $v2"
echo $v3            # Output: hello world
echo "$v3"          # Output: hello       world

#12


12  

Even if the += operator is now permitted, it has been introduced in Bash 3.1 in 2004.

即使+=操作符现在是允许的,它也在2004年的Bash 3.1中引入。

Any script using this operator on older Bash versions will fail with a "command not found" error if you are lucky, or a "syntax error near unexpected token".

如果幸运的话,任何在旧的Bash版本中使用该操作符的脚本都将失败,出现“未找到命令”错误,或者出现“接近意外令牌的语法错误”。

For those who cares about backward compatibility, stick with the older standard Bash concatenation methods, like those mentioned in the chosen answer:

对于那些关心向后兼容性的人,请坚持使用旧的标准Bash连接方法,如所选答案中提到的方法:

foo="Hello"
foo="$foo World"
echo $foo
> Hello World

#13


11  

Here is a concise summary of what most answers are talking about.

以下是对大多数答案的简要总结。

Let's say we have two variables:

假设有两个变量

a=hello
b=world

The table below explains the different contexts where we can combine the values of a and b to create a new variable, c.

下表解释了不同的上下文,在这些上下文中,我们可以组合a和b的值来创建一个新的变量c。

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

A few notes:

一些笔记:

  • enclosing the RHS of an assignment in double quotes is generally a good practice, though it is quite optional in many cases
  • 将作业的RHS用双引号括起来通常是一种很好的做法,尽管在很多情况下它是可选的
  • += is better from a performance standpoint if a big string is being constructed in small increments, especially in a loop
  • 从性能的角度来看,如果一个大的字符串正在以小的增量构建,特别是在循环中,那么就更好了。
  • use {} around variable names to disambiguate their expansion (as in row 2 in the table above)
  • 在变量名周围使用{}消除其展开的歧义(如上表第2行所示)

See also:

参见:

#14


10  

I prefer to use curly brackets ${} for expanding variable in string:

我更喜欢使用大括号${}在字符串中展开变量:

foo="Hello"
foo="${foo} World"
echo $foo
> Hello World

Curly brackets will fit to Continuous string usage:

大括号适用于连续字符串使用:

foo="Hello"
foo="${foo}World"
echo $foo
> HelloWorld

Otherwise using foo = "$fooWorld" will not work.

否则,使用foo = "$fooWorld"将不起作用。

#15


9  

The simplest way with quotation marks:

用引号括起来最简单的方法:

B=Bar
b=bar
var="$B""$b""a"
echo "Hello ""$var"

#16


6  

Safer way:

安全的方式:

a="AAAAAAAAAAAA"
b="BBBBBBBBBBBB"
c="CCCCCCCCCCCC"
d="DD DD"
s="${a}${b}${c}${d}"
echo "$s"
AAAAAAAAAAAABBBBBBBBBBBBCCCCCCCCCCCCDD DD

Strings containing spaces can become part of command, use "$XXX" and "${XXX}" to avoid these errors.

包含空格的字符串可以成为命令的一部分,使用“$XXX”和“${XXX}”来避免这些错误。

Plus take a look at other answer about +=

再看看其他关于+=的答案

#17


6  

There's one particular case where you should take care:

有一种情况你应该注意:

user=daniel
cat > output.file << EOF
"$user"san
EOF

Will output "daniel"san, and not danielsan, as you might have wanted. In this case you should do instead:

将输出“daniel”san,而不是danielsan,正如您可能希望的那样。在这种情况下,你应该这样做:

user=daniel
cat > output.file << EOF
${user}san
EOF

#18


5  

If what you are trying to do is to split a string into several lines, you can use a backslash:

如果你想做的是把一个字符串分成几行,你可以使用反斜杠:

$ a="hello\
> world"
$ echo $a
helloworld

With one space in between:

中间有一个空格:

$ a="hello \
> world"
$ echo $a
hello world

This one also adds only one space in between:

这一项也只在中间增加了一个空格:

$ a="hello \
>      world"
$ echo $a
hello world

#19


5  

var1='hello'
var2='world'
var3=$var1" "$var2 
echo $var3

#20


4  

If it is as your example of adding " World" to the original string, then it can be:

如果它是将“世界”添加到原始字符串的示例,那么它可以是:

#!/bin/bash

foo="Hello"
foo=$foo" World"
echo $foo

The output:

输出:

Hello World

#21


3  

Note that this won't work

注意,这行不通

foo=HELLO
bar=WORLD
foobar=PREFIX_$foo_$bar

as it seems to drop $foo and leaves you with:

因为它似乎掉了$foo,然后离开了你:

PREFIX_WORLD

PREFIX_WORLD

but this will work:

但这将工作:

foobar=PREFIX_"$foo"_"$bar"

and leave you with the correct output:

留给您正确的输出:

PREFIX_HELLO_WORLD

PREFIX_HELLO_WORLD

#22


2  

I do it this way when convenient: Use an inline command!

如果方便的话,我可以这样做:使用内联命令!

echo "The current time is `date`"
echo "Current User: `echo $USER`"

#23


2  

Here is the one through AWK:

这是通过AWK完成的:

$ foo="Hello"
$ foo=$(awk -v var=$foo 'BEGIN{print var" World"}')
$ echo $foo
Hello World

#24


2  

There are voiced concerns about performance, but no data is offered. Let me suggest a simple test.

有人表示对业绩感到担忧,但没有提供任何数据。让我建议一个简单的测试。

(NOTE: date on macOS does not offer nanoseconds, so this must be done on Linux.)

(注意:macOS上的日期不提供纳秒,所以这必须在Linux上完成。)

I have created append_test.sh on GitHub with the contents:

我已经创建了append_test。关于GitHub上的内容:

#!/bin/bash -e

output(){
    ptime=$ctime;
    ctime=$(date +%s.%N);
    delta=$(bc <<<"$ctime - $ptime");
    printf "%2s. %16s chars  time: %s  delta: %s\n" $n "$(bc <<<"10*(2^$n)")" $ctime $delta;
}

method1(){
    echo 'Method: a="$a$a"'
    for n in {1..32}; do a="$a$a"; output; done
}

method2(){
    echo 'Method: a+="$a"'
    for n in {1..32}; do a+="$a";  output; done
}

ctime=0; a="0123456789"; time method$1

Test 1:

测试1:

$ ./append_test.sh 1
Method: a="$a$a"
 1.               20 chars  time: 1513640431.861671143  delta: 1513640431.861671143
 2.               40 chars  time: 1513640431.865036344  delta: .003365201
 3.               80 chars  time: 1513640431.868200952  delta: .003164608
 4.              160 chars  time: 1513640431.871273553  delta: .003072601
 5.              320 chars  time: 1513640431.874358253  delta: .003084700
 6.              640 chars  time: 1513640431.877454625  delta: .003096372
 7.             1280 chars  time: 1513640431.880551786  delta: .003097161
 8.             2560 chars  time: 1513640431.883652169  delta: .003100383
 9.             5120 chars  time: 1513640431.886777451  delta: .003125282
10.            10240 chars  time: 1513640431.890066444  delta: .003288993
11.            20480 chars  time: 1513640431.893488326  delta: .003421882
12.            40960 chars  time: 1513640431.897273327  delta: .003785001
13.            81920 chars  time: 1513640431.901740563  delta: .004467236
14.           163840 chars  time: 1513640431.907592388  delta: .005851825
15.           327680 chars  time: 1513640431.916233664  delta: .008641276
16.           655360 chars  time: 1513640431.930577599  delta: .014343935
17.          1310720 chars  time: 1513640431.954343112  delta: .023765513
18.          2621440 chars  time: 1513640431.999438581  delta: .045095469
19.          5242880 chars  time: 1513640432.086792464  delta: .087353883
20.         10485760 chars  time: 1513640432.278492932  delta: .191700468
21.         20971520 chars  time: 1513640432.672274631  delta: .393781699
22.         41943040 chars  time: 1513640433.456406517  delta: .784131886
23.         83886080 chars  time: 1513640435.012385162  delta: 1.555978645
24.        167772160 chars  time: 1513640438.103865613  delta: 3.091480451
25.        335544320 chars  time: 1513640444.267009677  delta: 6.163144064
./append_test.sh: fork: Cannot allocate memory

Test 2:

测试2:

$ ./append_test.sh 2
Method: a+="$a"
 1.               20 chars  time: 1513640473.460480052  delta: 1513640473.460480052
 2.               40 chars  time: 1513640473.463738638  delta: .003258586
 3.               80 chars  time: 1513640473.466868613  delta: .003129975
 4.              160 chars  time: 1513640473.469948300  delta: .003079687
 5.              320 chars  time: 1513640473.473001255  delta: .003052955
 6.              640 chars  time: 1513640473.476086165  delta: .003084910
 7.             1280 chars  time: 1513640473.479196664  delta: .003110499
 8.             2560 chars  time: 1513640473.482355769  delta: .003159105
 9.             5120 chars  time: 1513640473.485495401  delta: .003139632
10.            10240 chars  time: 1513640473.488655040  delta: .003159639
11.            20480 chars  time: 1513640473.491946159  delta: .003291119
12.            40960 chars  time: 1513640473.495354094  delta: .003407935
13.            81920 chars  time: 1513640473.499138230  delta: .003784136
14.           163840 chars  time: 1513640473.503646917  delta: .004508687
15.           327680 chars  time: 1513640473.509647651  delta: .006000734
16.           655360 chars  time: 1513640473.518517787  delta: .008870136
17.          1310720 chars  time: 1513640473.533228130  delta: .014710343
18.          2621440 chars  time: 1513640473.560111613  delta: .026883483
19.          5242880 chars  time: 1513640473.606959569  delta: .046847956
20.         10485760 chars  time: 1513640473.699051712  delta: .092092143
21.         20971520 chars  time: 1513640473.898097661  delta: .199045949
22.         41943040 chars  time: 1513640474.299620758  delta: .401523097
23.         83886080 chars  time: 1513640475.092311556  delta: .792690798
24.        167772160 chars  time: 1513640476.660698221  delta: 1.568386665
25.        335544320 chars  time: 1513640479.776806227  delta: 3.116108006
./append_test.sh: fork: Cannot allocate memory

The errors indicate that my Bash got up to 335.54432 MB before it crashed. You could change the code from doubling the data to appending a constant to get a more granular graph and failure point. But I think this should give you enough information to decide whether you care. Personally, below 100 MB I don't. Your mileage may vary.

错误表明,我的Bash高达335.54432 MB,然后才崩溃。您可以更改代码,从将数据加倍到附加一个常量,以获得更细粒度的图形和故障点。但是我认为这应该给你足够的信息来决定你是否关心。就我个人而言,低于100mb我就不会。你的情况可能不同。

#25


1  

I kind of like making a quick function.

我喜欢做一个快速函数。

#! /bin/sh -f
function combo() {
    echo $@
}

echo $(combo 'foo''bar')

Yet another way to skin a cat. This time with functions :D

另一种剥猫皮的方法。这一次函数是D

#26


-1  

I don't know about PHP yet, but this works in Linux Bash. If you don't want to affect it to a variable, you could try this:

我还不知道PHP,但它在Linux Bash中工作。如果你不想影响到一个变量,你可以试试:

read pp;  *# Assumes I will affect Hello to pp*
pp=$( printf $pp ;printf ' World'; printf '!');
echo $pp;

>Hello World!

You could place another variable instead of 'Hello' or '!'. You could concatenate more strings as well.

您可以放置另一个变量,而不是“Hello”或“!”你也可以连接更多的字符串。

#27


-3  

You can try the below way. When substitution takes place, double quotes will keep the spaces.

你可以试试下面的方法。当发生替换时,双引号将保留空格。

var1="Ram "    
var2="Lakshmana" 
echo $var1$var2
or 
echo var1+=$var2 "bash support += operation.

bcsmc2rtese001 [/tmp]$ var1="Ram "  
bcsmc2rtese001 [/tmp]$ var2="Lakshmana"  
bcsmc2rtese001 [/tmp]$ echo $var1$var2  
Ram Lakshmana  

bcsmc2rtese001 [/tmp]$ var1+=$var2  
bcsmc2rtese001 [/tmp]$ echo $var1  
Ram Lakshmana
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值