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

发布于 2024-10-02 15:10:17 字数 171 浏览 10 评论 0原文

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

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

这里,$foo 变为 "Hello World"

这在 Bash 中是如何实现的?

In PHP, strings are concatenated together as follows:

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

Here, $foo becomes "Hello World".

How is this accomplished in Bash?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(30

网白 2024-10-09 15:10:17
foo="Hello"
foo="${foo} World"
echo "${foo}"
> Hello World

一般来说,要连接两个变量,您可以将它们一个接一个地写入:

a='Hello'
b='World'
c="${a} ${b}"
echo "${c}"
> Hello World
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
无声无音无过去 2024-10-09 15:10:17

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

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

输出

XYZ

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

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

output

X Y Z

箹锭⒈辈孓 2024-10-09 15:10:17

首先是 Bash

因为这个问题专门针对 Bash,我的答案的第一部分将提供正确执行此操作的不同方法:

+=:附加到变量

语法 += 可以以不同的方式使用:

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

(因为我很节俭,所以我只会使用两个变量 fooa,然后在完整答案。;-)

a=2
a+=4
echo $a
24

使用堆栈溢出问题语法,

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

效果很好!

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

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

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

附加到整数声明的变量:var+=。 ..

在 bash 下,一旦声明变量,您就可以使用整数:

declare -i iVal
iVal=7
iVal+=iVal+iVal+iVal+iVal+iVal

declare -i iVal
iVal=7
iVal+=' iVal * 5 '

echo $iVal
42

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

我们的 a 也是一个仅包含一个元素的数组。

echo ${a[@]}
36
a+=(18)

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

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

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

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

a+=(one word "hello world"! 'hello world!' 
declare -a a=([0]="36" [1]="18" [2]="one" [3]="word" [4]="hello world!" [5]="hel
lo world!" [6]="hello world!" [7]="hello world!")

其中 6 个字段一个 单词 和 4 x hello world!),添加到数组 $ {ar[@]} 已包含 3818

注意:您可以< strong>将字符串追加到数组中:

a+=(foo)
a[8]+=' bar'
declare -p a
declare -a a=([0]="36" [1]="18" [2]="one" [3]="word" [4]="hello world!" [5]="hel
lo world!" [6]="hello world!" [7]="hello world!" [8]="foo bar")

当然,如果array被声明为整数,bash将尝试解析整数操作:

declare -ai iVal
iVal=({3..12..4})
iVal[1]+=' iVal[1] * 5 '
echo ${iVal[1]}
42

printf:重新-使用 builtin 命令构造变量

printf builtin 命令提供了一种绘制字符串格式的强大方法,因为这是 Bash builtin<。 /em>,有一个选项可以将格式化字符串发送到变量,而不是在 stdout 上打印:

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

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

printf -v a "%s./.%s...'%s' '%s', '%s'=='%s'=='%s'=='%s' <%q>" "${a[@]}"
echo $a
36./.18...'one' 'word', 'hello world!'=='hello world!'=='hello world!'=='hello w
orld!', <foo\ bar>

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

请注意,我们的a仍然是一个数组!仅更改第一个元素!

declare -p a
declare -a a=([0]="36./.18...'one' 'word', 'hello world!'=='hello world!'=='hell
o world!'=='hello world!', <foo\\ bar>" [1]="18" [2]="one" [3]="word" [4]="hello
 world!" [5]="hello world!" [6]="hello world!" [7]="hello world!" [8]="foo bar")

在 bash 下,当您访问变量名而不指定索引时,您始终只寻址第一个元素!

因此,要检索我们的九个字段数组,我们只需要重新设置第一个元素:

a=36
declare -p a
declare -a a=([0]="36" [1]="18" [2]="one" [3]="word" [4]="hello world!" [5]="hel
lo world!" [6]="hello world!" [7]="hello world!" [8]="foo bar")

一个参数格式字符串,其中传递多个参数:

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

使用堆栈溢出问题语法:

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

注意:的使用>双引号对于操作包含空格制表和/或换行符的字符串可能很有用,

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

现在在Shell

POSIX shell,您不能使用bashisms,因此没有内置的printf。

基本上

但是你可以简单地这样做:

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

在另一边:

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

但是如果你想在变量之后立即添加字母,没有空格,你可能需要使用大括号:

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

格式化,使用分叉 printf

如果你想使用更复杂的结构,你必须使用fork(新的子进程,它完成工作并通过 stdout 返回结果code>):

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

从历史上看,您可以使用反引号来检索分叉的结果:

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

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

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

使用反引号,您可以必须用反斜杠转义内部分叉:

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

更多..

玩字符串,看看:

hello world\041' hello\ world\!) declare -p a

其中 6 个字段一个 单词 和 4 x hello world!),添加到数组 $ {ar[@]} 已包含 3818

注意:您可以< strong>将字符串追加到数组中:

当然,如果array被声明为整数,bash将尝试解析整数操作:

printf:重新-使用 builtin 命令构造变量

printf builtin 命令提供了一种绘制字符串格式的强大方法,因为这是 Bash builtin<。 /em>,有一个选项可以将格式化字符串发送到变量,而不是在 stdout 上打印:

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

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

请注意,我们的a仍然是一个数组!仅更改第一个元素!

在 bash 下,当您访问变量名而不指定索引时,您始终只寻址第一个元素!

因此,要检索我们的九个字段数组,我们只需要重新设置第一个元素:

一个参数格式字符串,其中传递多个参数:

使用堆栈溢出问题语法:

注意:的使用>双引号对于操作包含空格制表和/或换行符的字符串可能很有用,

现在在Shell

POSIX shell,您不能使用bashisms,因此没有内置的printf。

基本上

但是你可以简单地这样做:

在另一边:

但是如果你想在变量之后立即添加字母,没有空格,你可能需要使用大括号:

格式化,使用分叉 printf

如果你想使用更复杂的结构,你必须使用fork(新的子进程,它完成工作并通过 stdout 返回结果code>):

从历史上看,您可以使用反引号来检索分叉的结果:

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

使用反引号,您可以必须用反斜杠转义内部分叉:

更多..

玩字符串,看看:

Bash first

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

+=: 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. ;-)

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

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

Append to an interger declared variable: var+=...

Under bash, you could work in integer once variable is declared:

declare -i iVal
iVal=7
iVal+=iVal+iVal+iVal+iVal+iVal

or

declare -i iVal
iVal=7
iVal+=' iVal * 5 '

echo $iVal
42

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

Our a is also an array of only one element.

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:

a+=(one word "hello world"! 'hello world!' 
declare -a a=([0]="36" [1]="18" [2]="one" [3]="word" [4]="hello world!" [5]="hel
lo world!" [6]="hello world!" [7]="hello world!")

Where 6 fields (one, word and 4 x hello world!), where added to array ${ar[@]} which already contained 38 and 18.

Note: you could append to a string into an array:

a+=(foo)
a[8]+=' bar'
declare -p a
declare -a a=([0]="36" [1]="18" [2]="one" [3]="word" [4]="hello world!" [5]="hel
lo world!" [6]="hello world!" [7]="hello world!" [8]="foo bar")

Of course if array is declared as in integer, bash will try to resolve integer operation:

declare -ai iVal
iVal=({3..12..4})
iVal[1]+=' iVal[1] * 5 '
echo ${iVal[1]}
42

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 formatted string to a variable instead of printing on stdout:

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

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

printf -v a "%s./.%s...'%s' '%s', '%s'=='%s'=='%s'=='%s' <%q>" "${a[@]}"
echo $a
36./.18...'one' 'word', 'hello world!'=='hello world!'=='hello world!'=='hello w
orld!', <foo\ bar>

Or we could use one argument format string which will be repeated as many argument submitted...

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

declare -p a
declare -a a=([0]="36./.18...'one' 'word', 'hello world!'=='hello world!'=='hell
o world!'=='hello world!', <foo\\ bar>" [1]="18" [2]="one" [3]="word" [4]="hello
 world!" [5]="hello world!" [6]="hello world!" [7]="hello world!" [8]="foo bar")

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

So to retrieve our nine 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]="hel
lo world!" [6]="hello world!" [7]="hello world!" [8]="foo bar")

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!>
<hello world!>
<foo bar>

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 spaces, tabulations and/or newlines

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

Shell now

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

Basically

But you could simply do:

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

In the other side:

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

But if you want to add letters immediately after your variable, without space, you may need to use braces:

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):

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

Historically, you could use backticks for retrieving result of a 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

More..

Playing with strings, have a look at:

hello world\041' hello\ world\!) declare -p a

Where 6 fields (one, word and 4 x hello world!), where added to array ${ar[@]} which already contained 38 and 18.

Note: you could append to a string into an array:

Of course if array is declared as in integer, bash will try to resolve integer operation:

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 formatted string to a variable instead of printing on stdout:

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

Or we could use one argument format string which will be repeated as many argument submitted...

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

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

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

One argument format string with many argument passed to:

Using the Stack Overflow question syntax:

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

Shell now

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

Basically

But you could simply do:

In the other side:

But if you want to add letters immediately after your variable, without space, you may need to use braces:

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):

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

But this is not easy for nesting:

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

More..

Playing with strings, have a look at:

半步萧音过轻尘 2024-10-09 15:10:17

你也可以这样做:

$ var="myscript"

$ echo $var

myscript


$ var=${var}.sh

$ echo $var

myscript.sh

You can do this too:

$ var="myscript"

$ echo $var

myscript


$ var=${var}.sh

$ echo $var

myscript.sh
贪了杯 2024-10-09 15:10:17
bla=hello
laber=kthx
echo "${bla}ohai${laber}bye"

将输出

helloohaikthxbye

这在以下情况下很有用
$blaohai
导致变量未找到错误。或者如果字符串中有空格或其他特殊字符。 "${foo}" 正确转义您放入其中的任何内容。

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.

把回忆走一遍 2024-10-09 15:10:17
foo="Hello "
foo="$foo World"

    

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

     

皇甫轩 2024-10-09 15:10:17

以下是大多数答案所讨论内容的简要总结。

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

set one two
a=hello
b=world

下表解释了不同的上下文,我们可以在其中组合 ab 的值来创建新变量变量,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=$1world             | 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

一些注意事项:

  • 将赋值的 RHS 用双引号括起来通常是一种很好的做法,尽管在许多情况下它是相当可选的,
  • 如果在中构建大字符串,则从性能角度来看 += 会更好小增量,尤其是在循环中,
  • 在变量名称周围使用 {} 来消除其扩展的歧义(如上表中的第 2 行所示)。如第 3 行和第 4 行所示,除非变量与以 shell 变量名称中有效第一个字符(即字母表)开头的字符串连接,否则不需要 {}或下划线。

另请参阅:

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':

set one two
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.

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=$1world             | 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.

See also:

无悔心 2024-10-09 15:10:17

我解决问题的方法就是例如

$a$b

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

它会产生

Hello World

例如,如果您尝试将一个字符串与另一个字符串连接,

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

那么 echo "$c" 将产生

Hello World

一个额外的空格。

$aWorld

并不像你想象的那样工作,但

${a}World

会产生

HelloWorld

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

Hello World

with an extra space.

$aWorld

doesn't work, as you may imagine, but

${a}World

produces

HelloWorld
记忆之渊 2024-10-09 15:10:17
$ a=hip
$ b=hop
$ ab=$a$b
$ echo $ab
hiphop
$ echo $a$b
hiphop
$ a=hip
$ b=hop
$ ab=$a$b
$ echo $ab
hiphop
$ echo $a$b
hiphop
新人笑 2024-10-09 15:10:17

另一种方法……

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

又一种方法。

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

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.
韵柒 2024-10-09 15:10:17

如果您想附加下划线之类的内容,请使用转义符 (\)

FILEPATH=/opt/myfile

不起作用

echo $FILEPATH_$DATEX

这工作正常:

echo $FILEPATH\\_$DATEX

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

FILEPATH=/opt/myfile

This does not work:

echo $FILEPATH_$DATEX

This works fine:

echo $FILEPATH\\_$DATEX
撧情箌佬 2024-10-09 15:10:17

最简单的加引号的方式:

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

The simplest way with quotation marks:

B=Bar
b=bar
var="$B""$b""a"
echo "Hello ""$var"
毁梦 2024-10-09 15:10:17

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

如果幸运的话,在较旧的 Bash 版本上使用此运算符的任何脚本都会失败,并出现“找不到命令”错误,或“意外标记附近的语法错误”。

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

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

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

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".

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

foo="Hello"
foo="$foo World"
echo $foo
> Hello World
橙幽之幻 2024-10-09 15:10:17

默认情况下,Bash 中的变量和数组(索引或关联*)始终是字符串,但您可以使用 declare 内置标志,为它们提供诸如“整数”之类的属性(-i) 或“引用”** (-n),这会改变它们的行为方式。

Bash 算术接受 ASCII/字符串数字作为输入,因此几乎没有理由实际使用整数属性。

另外,变量值不能包含 ASCII NULL(即 8 位零),因为使用常规的 null 终止 C 字符串来实现它们。

* 即一个或多个键+值对。
** 引用变量扩展为另一个变量的值,该变量的标签分配给引用变量

附加字符串:

$ foo=Hello
$ foo+=' world!'
$ echo "$foo"

Hello world!

$ num=3
$ num+=4
echo "$num"

34 # Appended string (not a sum)

使用整数属性的几个原因之一是,它改变了引用变量的行为+= 赋值运算符:

$ declare -i num=3
$ num+=4
echo "$num"

7 # Sum

请注意,这不适用于 -=/= 等,除非您在算术内部执行此操作(< code>(( )) 和 $(( ))),其中无论是否带有整数属性,数字都已被视为相同。有关这些运算符的完整列表,请参阅 man bash 的“算术求值”部分,这些运算符与 C 中的相同。

+= 赋值运算符也可以用于将新元素附加到索引数组(又名“列表”):

$ foo=(one)
$ foo+=(two)
$ printf 'Separate element: %s\n' "${foo[@]}"

Separate element: one
Separate element: two

执行此操作的另一种常见方法是使用计数器:

$ foo[c++]=one
$ foo[c++]=two

POSIX shell使用< code>+= 赋值运算符附加字符串,所以你必须这样做:

$ foo=Hello
$ foo="$foo world!"
$ echo "$foo"

Hello world!

这在 Bash 中也很好,所以它可以被认为是一种更可移植的语法。

Variables and arrays (indexed or associative*) in Bash are always strings by default, but you can use flags to the declare builtin, to give them attributes like "integer" (-i) or "reference"** (-n), which change the way they behave.

Bash arithmetic accepts ASCII/string numbers for input, so there are few reasons to actually use the integer attribute.

Also, variable values can't contain ASCII NULL (i.e., 8 bit zero), because regular null terminated C strings are used to implement them.

* Ie one or more key + value pairs.
** Reference variables expand to the value of another variable, whose label is assigned to the reference variable

Append a string:

$ foo=Hello
$ foo+=' world!'
$ echo "$foo"

Hello world!

$ num=3
$ num+=4
echo "$num"

34 # Appended string (not a sum)

One of the few reasons to use the integer attribute, is that it changes the behaviour of the += assignment operator:

$ declare -i num=3
$ num+=4
echo "$num"

7 # Sum

Note that this doesn't work for -=, /=, etc. unless you do it inside arithmetic ((( )) and $(( ))), where numbers are already treated the same with or without the integer attribute. See the section "arithmetic evaluation" of man bash for a full list of those operators, which are the same as for C.

The += assignment operator can also be used to append new elements to an indexed array (AKA "list"):

$ foo=(one)
$ foo+=(two)
$ printf 'Separate element: %s\n' "${foo[@]}"

Separate element: one
Separate element: two

Another common way to do this is to use a counter:

$ foo[c++]=one
$ foo[c++]=two

POSIX shells do not use the += assignment operator to append strings, so you have to do it like this:

$ foo=Hello
$ foo="$foo world!"
$ echo "$foo"

Hello world!

This is fine in Bash too, so it could be considered a more portable syntax.

静若繁花 2024-10-09 15:10:17

您可以不使用引号进行连接。下面是一个示例:

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

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

这是 Bash 脚本的示例:

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

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).

This is an example of a Bash script:

v1=hello
v2=world
v3="$v1       $v2"
echo $v3            # Output: hello world
echo "$v3"          # Output: hello       world
手心的温暖 2024-10-09 15:10:17

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

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

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

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

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

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.

葮薆情 2024-10-09 15:10:17

尽管有特殊的运算符 += 用于连接,但还有一种更简单的方法:

foo='Hello'
foo=$foo' World'
echo $foo

双引号需要额外的计算时间来解释内部变量。如果可能的话避免它。

Despite of the special operator, +=, for concatenation, there is a simpler way to go:

foo='Hello'
foo=$foo' World'
echo $foo

Double quotes take an extra calculation time for interpretation of variables inside. Avoid it if possible.

流年已逝 2024-10-09 15:10:17

更安全的方法:

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

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

另外看看关于+=的其他答案

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.

Plus take a look at other answer about +=

挽容 2024-10-09 15:10:17

您应该注意一种特殊情况:

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

将输出 "daniel"san,而不是您可能想要的 danielsan
在这种情况下,你应该这样做:

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

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:

user=daniel
cat > output.file << EOF
${user}san
EOF
↙厌世 2024-10-09 15:10:17

如果您想要将一个字符串分割为多行,则可以使用反斜杠:

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

中间有一个空格:

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

这也仅在中间添加一个空格:

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

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
一生独一 2024-10-09 15:10:17

有人表达了对性能的担忧,但没有提供任何数据。让我建议一个简单的测试。

(注意:macOS 上的 date 不提供纳秒,因此必须在 Linux 上完成。)

我创建了 GitHub 上的append_test.sh,内容为:

#!/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

测试 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

测试 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

错误表明我的 Bash 在崩溃之前达到了 335.54432 MB。您可以将代码从将数据加倍更改为附加常量以获得更精细的图表和失败观点。但我认为这应该为您提供足够的信息来决定您是否关心。就我个人而言,低于 100MB 我不会。您的里程可能会有所不同。

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.)

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

#!/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:

$ ./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:

$ ./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.

甜是你 2024-10-09 15:10:17
a="Hello,"
a=$a" World!"
echo $a

这就是连接两个字符串的方法。

a="Hello,"
a=$a" World!"
echo $a

This is how you concatenate two strings.

橪书 2024-10-09 15:10:17

如果它是在原始字符串中添加 " World" 的示例,那么它可以是:

#!/bin/bash

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

输出:

Hello World

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
勿忘初心 2024-10-09 15:10:17
var1='hello'
var2='world'
var3=$var1" "$var2 
echo $var3
var1='hello'
var2='world'
var3=$var1" "$var2 
echo $var3
寂寞花火° 2024-10-09 15:10:17

我想从列表中构建一个字符串。找不到答案,所以我将其发布在这里。这就是我所做的:

list=(1 2 3 4 5)
string=''

for elm in "${list[@]}"; do
    string="${string} ${elm}"
done

echo ${string}

然后我得到以下输出:

1 2 3 4 5

I wanted to build a string from a list. Couldn't find an answer for that so I post it here. Here is what I did:

list=(1 2 3 4 5)
string=''

for elm in "${list[@]}"; do
    string="${string} ${elm}"
done

echo ${string}

and then I get the following output:

1 2 3 4 5
痴情换悲伤 2024-10-09 15:10:17

请注意,这不起作用

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

,因为它似乎会删除 $foo 并留下:

PREFIX_WORLD

但这会起作用:

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

并为您留下正确的输出:

PREFIX_HELLO_WORLD

Note that this won't work

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

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

PREFIX_WORLD

but this will work:

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

and leave you with the correct output:

PREFIX_HELLO_WORLD

彼岸花似海 2024-10-09 15:10:17

以下是 AWK 的内容:

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

Here is the one through AWK:

$ foo="Hello"
$ foo=$(awk -v var=$foo 'BEGIN{print var" World"}')
$ echo $foo
Hello World
仄言 2024-10-09 15:10:17

我在方便的时候这样做:使用内联命令!

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

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

echo "The current time is `date`"
echo "Current User: `echo $USER`"
安稳善良 2024-10-09 15:10:17

在我看来,连接两个字符串的最简单方法是编写一个为您执行此操作的函数,然后使用该函数。

function concat ()
{
    prefix=$1
    suffix=$2

    echo "${prefix}${suffix}"
}

foo="Super"
bar="man"

concat $foo $bar   # Superman

alien=$(concat $foo $bar)

echo $alien        # Superman

In my opinion, the simplest way to concatenate two strings is to write a function that does it for you, then use that function.

function concat ()
{
    prefix=$1
    suffix=$2

    echo "${prefix}${suffix}"
}

foo="Super"
bar="man"

concat $foo $bar   # Superman

alien=$(concat $foo $bar)

echo $alien        # Superman
木緿 2024-10-09 15:10:17

还可以在 Bash 4.x 中使用命名引用,将任意字符串添加到引用的字符串中(每个字符串由引用的分隔符分隔):

delcare str='S1'
declare separator=','

# Appends to str ref #1, separated by sep ref #2
app_str() {
    local -n str="$1"
    local -n sep="$2"
    local -a appends=("${@:3}")
    local -i appsLen=${#appends[@]}
    local -i i
    # If any appends, add 1st sep to referenced str
    if [[ $appsLen -gt 0 ]]; then
        str+="${sep}"   
    fi
    for appStr in "${appends[@]}"; do
        str+="$appStr"
        if [[ $((++i)) -lt $appsLen ]]; then
            str+="${sep}"
        fi
    done
}

像这样使用它:

app_str str separator 'S2' 'S3' 'S4'
echo -e "$str"

另一种追加(和分隔)的方法) 与 `printf`:

declare separator=','
declare testStr='STR1'
declare -a testArr=(STR2 STR3 STR4)
testStr="$testStr"$(printf "$separator%s" "${testArr[@]}")

echo -e "$testStr"

There's also the possibility to use named references in Bash 4.x, to add arbitrary strings to the referenced string (delimited by a referenced separator each):

delcare str='S1'
declare separator=','

# Appends to str ref #1, separated by sep ref #2
app_str() {
    local -n str="$1"
    local -n sep="$2"
    local -a appends=("${@:3}")
    local -i appsLen=${#appends[@]}
    local -i i
    # If any appends, add 1st sep to referenced str
    if [[ $appsLen -gt 0 ]]; then
        str+="${sep}"   
    fi
    for appStr in "${appends[@]}"; do
        str+="$appStr"
        if [[ $((++i)) -lt $appsLen ]]; then
            str+="${sep}"
        fi
    done
}

Use it like so:

app_str str separator 'S2' 'S3' 'S4'
echo -e "$str"

Another way to append (and separate) with `printf``:

declare separator=','
declare testStr='STR1'
declare -a testArr=(STR2 STR3 STR4)
testStr="$testStr"$(printf "$separator%s" "${testArr[@]}")

echo -e "$testStr"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文