如何在 Bash 中连接字符串变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4181703/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 19:53:11  来源:igfitidea点击:

How to concatenate string variables in Bash

bashshellsyntaxconcatstring-concatenation

提问by Strawberry

In PHP, strings are concatenated together as follows:

在 PHP 中,字符串按如下方式连接在一起:

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

Here, $foobecomes "Hello World".

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

How is this accomplished in Bash?

这是如何在 Bash 中实现的?

回答by codaddict

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}"
> Hello World

回答by thkala

Bash also supports a +=operator as shown in this code:

Bash 还支持+=如下代码所示的运算符:

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

回答by F. Hauri

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+=...

附加到字符串 var+=...

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

(因为我节俭,我只会用两个变量foo,并a在整个答案,然后再使用相同的。;-)

a=2
a+=4
echo $a
24

Using the Stack Overflow questionsyntax,

使用Stack Overflow 问题语法,

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

works fine!

工作正常!

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

附加到一个整数 ((var+=...))

variable ais a string, but also an integer

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

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

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

追加到数组 var+=(...)

Our ais 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:

嗯..这不是一个错误,而是一个功能......为了防止 bash 尝试开发!",你可以:

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

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 builtincommand

printf: 使用内置命令重新构造变量

The printfbuiltincommand gives a powerful way of drawing string format. As this is a Bash builtin, there is a option for sending formatted 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 stringsin this array. So we could build a formatted string containing exactly seven positional arguments:

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

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 stringwhich will be repeated as many argument submitted...

或者我们可以使用一个参数格式字符串,该字符串将重复提交的参数数量...

Note that our ais 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 questionsyntax:

使用Stack Overflow 问题语法:

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

Nota: The use of double-quotesmay be useful for manipulating strings that contain spaces, tabulationsand/or newlines

注意:双引号的使用可能有助于处理包含spaces,tabulations和/或newlines

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

Shell now

现在壳

Under POSIXshell, you could not use bashisms, so there is no builtinprintf.

POSIXshell 下,你不能使用bashisms,所以没有builtinprintf

Basically

基本上

But you could simply do:

但你可以简单地做:

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

Formatted, using forkedprintf

格式化,使用分叉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 backticksfor 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

回答by userend

You can do this too:

你也可以这样做:

$ var="myscript"

$ echo $var

myscript


$ var=${var}.sh

$ echo $var

myscript.sh

回答by orkoden

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

Will output

会输出

helloohaikthxbye

This is useful when $blaohaileads 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导致变量未找到错误时很有用 。或者,如果您的字符串中有空格或其他特殊字符。"${foo}"正确地逃脱你放入其中的任何东西。

回答by vinothkr

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

     

     

回答by Chris Smith

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

回答by bcosca

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

回答by codeforester

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

这是大多数答案所谈论的内容的简明摘要。

Let's say we have two variables and $1 is set to 'one':

假设我们有两个变量,并且 $1 设置为“一”:

set one two
a=hello
b=world

The table below explains the different contexts where we can combine the values of aand bto 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 and a literal              | c=world             | oneworld
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
  • +=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). As seen on rows 3 and 4, there is no need for {}unless a variable is being concatenated with a string that starts with a character that is a valid first character in shell variable name, that is alphabet or underscore.
  • 用双引号将赋值的 RHS 括起来通常是一种很好的做法,尽管在许多情况下它是完全可选的
  • +=如果以小增量构造大字符串,尤其是在循环中,则从性能的角度来看会更好
  • 使用{}围绕变量名称来消除它们的扩展歧义(如上表中的第 2 行)。如第 3 行和第 4 行所示,{}除非变量与以 shell 变量名称中有效第一个字符(即字母表或下划线)开头的字符串连接,否则不需要。


See also:

也可以看看:

回答by Akseli Palén

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.