在PHP中,字符串连接在一起如下:
$foo = "Hello";
$foo .= " World";
在这里,$foo
成为“Hello World”。
这是如何在Bash中完成的?
答案 0 :(得分:3312)
foo="Hello"
foo="$foo World"
echo $foo
> Hello World
一般来说,要连接两个变量,你可以一个接一个地写它们:
a='hello'
b='world'
c="$a$b"
echo $c
> helloworld
答案 1 :(得分:1034)
Bash还支持+=
运算符,如以下代码所示:
$ A="X Y"
$ A+=" Z"
$ echo "$A"
X Y Z
答案 2 :(得分:890)
由于这个问题专门针对Bash,我的答案的第一部分会提出不同的方法:
+=
:附加到变量语法 +=
可能会以不同的方式使用:
var+=...
(因为我节俭,我只会使用两个变量foo
和a
,然后在整个答案中重复使用它。; - )
a=2
a+=4
echo $a
24
使用 Stack Overflow问题语法,
foo="Hello"
foo+=" World"
echo $foo
Hello World
工作正常!
((var+=...))
变量a
是一个字符串,但也是一个整数
echo $a
24
((a+=12))
echo $a
36
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
嗯...... this is not a bug, but a feature ...为防止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
:使用内置命令重构变量 printf
builtin 命令提供了一种绘制字符串格式的强大方法。由于这是Bash 内置,因此可以选择将格式化字符串发送到变量而不是在stdout
上打印:
echo ${a[@]}
36 18 one word hello world! hello world! hello world!
此数组中有七个字符串。所以我们可以构建一个包含七个位置参数的格式化字符串:
printf -v a "%s./.%s...'%s' '%s', '%s'=='%s'=='%s'" "${a[@]}"
echo $a
36./.18...'one' 'word', 'hello world!'=='hello world!'=='hello world!'
或者我们可以使用一个参数格式字符串,这将在提交的参数中重复...
请注意,我们的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!")'
在bash下,当你在不指定索引的情况下访问变量名时,你总是只对第一个元素进行处理!
因此,为了检索我们的七个字段数组,我们只需要重新设置第一个元素:
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!")'
一个参数格式字符串,其中包含许多参数传递给:
printf -v a[0] '<%s>\n' "${a[@]}"
echo "$a"
<36>
<18>
<one>
<word>
<hello world!>
<hello world!>
<hello world!>
foo="Hello"
printf -v foo "%s World" $foo
echo $foo
Hello World
Nota:使用双引号可能对操作包含spaces
,tabulations
和/或newlines
printf -v foo "%s World" "$foo"
在 POSIX shell下,您无法使用 bashisms ,因此没有内置 printf
。
但你可以这样做:
foo="Hello"
foo="$foo World"
echo $foo
Hello World
printf
如果你想使用更复杂的结构,你必须使用 fork (创建作业并通过stdout
返回结果的新子进程):
foo="Hello"
foo=$(printf "%s World" "$foo")
echo $foo
Hello World
从历史上看,您可以使用反引号来检索 fork 的结果:
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
答案 3 :(得分:124)
您也可以这样做:
$ var="myscript"
$ echo $var
myscript
$ var=${var}.sh
$ echo $var
myscript.sh
答案 4 :(得分:115)
bla=hello
laber=kthx
echo "${bla}ohai${laber}bye"
将输出
helloohaikthxbye
这很有用
$blaohai
导致变量未找到错误。或者如果字符串中有空格或其他特殊字符。 "${foo}"
正确地逃避了你投入的任何事情。
答案 5 :(得分:42)
foo="Hello "
foo="$foo World"
答案 6 :(得分:32)
我解决问题的方法就是
$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
答案 7 :(得分:27)
$ a=hip
$ b=hop
$ ab=$a$b
$ echo $ab
hiphop
$ echo $a$b
hiphop
答案 8 :(得分:20)
以下是大多数答案所讨论的简要摘要。
我们假设我们有两个变量,$ 1设置为&#39;一个&#39;:
set one two
a=hello
b=world
下表说明了我们可以将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=$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
一些注意事项:
+=
从性能的角度来看会更好,尤其是在循环中{}
来消除其扩展的歧义(如上表中的第2行)。如第3行和第4行所示,除非变量与字符串连接,否则不需要{}
,该字符串以shell变量名中有效的第一个字符开头,即字母或下划线。 / LI>
另见:
答案 9 :(得分:20)
如果要附加下划线之类的内容,请使用escape(\)
FILEPATH=/opt/myfile
这不工作:
echo $FILEPATH_$DATEX
这很好用:
echo $FILEPATH\\_$DATEX
答案 10 :(得分:19)
又一种方法......
> H="Hello "
> U="$H""universe."
> echo $U
Hello universe.
......还有一个。
> H="Hello "
> U=$H"universe."
> echo $U
Hello universe.
答案 11 :(得分:15)
您可以在没有引号的情况下连接。这是一个例子:
$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
答案 12 :(得分:15)
引号最简单的方法:
B=Bar
b=bar
var="$B""$b""a"
echo "Hello ""$var"
答案 13 :(得分:14)
即使现在允许+ =运算符,它也已在2004年的 Bash 3.1 中引入。
在较旧的Bash版本上使用此运算符的任何脚本都将失败,如果您幸运,则会出现“未找到命令”错误,或“意外令牌附近的语法错误”。
对于那些关心向后兼容性的人,请坚持使用旧的标准Bash级联方法,如所选答案中提到的那样:
foo="Hello"
foo="$foo World"
echo $foo
> Hello World
答案 14 :(得分:13)
我更喜欢使用大括号${}
来扩展字符串中的变量:
foo="Hello"
foo="${foo} World"
echo $foo
> Hello World
圆括号适合连续字符串用法:
foo="Hello"
foo="${foo}World"
echo $foo
> HelloWorld
否则使用foo = "$fooWorld"
将无效。
答案 15 :(得分:7)
更安全的方式:
a="AAAAAAAAAAAA"
b="BBBBBBBBBBBB"
c="CCCCCCCCCCCC"
d="DD DD"
s="${a}${b}${c}${d}"
echo "$s"
AAAAAAAAAAAABBBBBBBBBBBBCCCCCCCCCCCCDD DD
包含空格的字符串可以成为命令的一部分,使用“$ XXX”和“$ {XXX}”来避免这些错误。
另外,请看一下 + =
的其他答案答案 16 :(得分:7)
如果你要做的是将拆分一个字符串分成几行,你可以使用反斜杠:
$ a="hello\
> world"
$ echo $a
helloworld
中间有一个空格:
$ a="hello \
> world"
$ echo $a
hello world
这个也只增加了一个空格:
$ a="hello \
> world"
$ echo $a
hello world
答案 17 :(得分:6)
您应该注意的一个特殊情况:
user=daniel
cat > output.file << EOF
"$user"san
EOF
将输出"daniel"san
,而不是danielsan
,就像您可能想要的那样。
在这种情况下,你应该做:
user=daniel
cat > output.file << EOF
${user}san
EOF
答案 18 :(得分:5)
如果它是将" World"
添加到原始字符串的示例,那么它可以是:
#!/bin/bash
foo="Hello"
foo=$foo" World"
echo $foo
输出:
Hello World
答案 19 :(得分:5)
var1='hello'
var2='world'
var3=$var1" "$var2
echo $var3
答案 20 :(得分:4)
a="Hello,"
a=$a" World!"
echo $a
这是连接两个字符串的方式。
答案 21 :(得分:4)
我想从列表中构建一个字符串。找不到答案,所以我在这里发布。这是我所做的:
list=(1 2 3 4 5)
string=''
for elm in "${list[@]}"; do
string="${string} ${elm}"
done
echo ${string}
然后我得到以下输出:
1 2 3 4 5
答案 22 :(得分:4)
有人对性能表示担忧,但没有提供数据。让我建议一个简单的测试。
(注意:macOS上的date
不提供纳秒,因此必须在Linux上完成。)
我创建了append_test.sh on 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
测试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 。您可以将the code更改为将数据加倍,以附加常量以获得更精细的图形和故障点。但我认为这应该给你足够的信息来决定你是否关心。就个人而言,低于100 MB,我没有。您的里程可能会有所不同。
答案 23 :(得分:3)
请注意,这不起作用
foo=HELLO
bar=WORLD
foobar=PREFIX_$foo_$bar
因为它似乎放弃了$ foo而离开了你:
PREFIX_WORLD
但这会奏效:
foobar=PREFIX_"$foo"_"$bar"
并留下正确的输出:
PREFIX_HELLO_WORLD
答案 24 :(得分:1)
以下是AWK:
之一$ foo="Hello"
$ foo=$(awk -v var=$foo 'BEGIN{print var" World"}')
$ echo $foo
Hello World
答案 25 :(得分:1)
尽管使用特殊运算符+=
进行串联,但还有一种更简单的方法:
foo='Hello'
foo=$foo' World'
echo $foo
双引号会花费额外的计算时间来解释内部变量,请尽可能避免。
答案 26 :(得分:1)
我方便的时候这样做:使用内联命令!
echo "The current time is `date`"
echo "Current User: `echo $USER`"
答案 27 :(得分:0)
我认为,连接两个字符串的最简单方法是编写一个为您执行此操作的函数,然后使用该函数。
function concat ()
{
prefix=$1
suffix=$2
echo "${prefix}${suffix}"
}
foo="Super"
bar="man"
concat $foo $bar # Superman
alien=$(concat $foo $bar)
echo $alien # Superman
答案 28 :(得分:0)
bash 中的变量和数组(索引或关联*)在默认情况下始终是字符串,但您可以使用 declare
内置的标志,为它们提供诸如“整数”(-i
)或“引用”** (-n
),这会改变它们的行为方式。
Bash 算法接受 ASCII/字符串数字作为输入,因此几乎没有理由实际使用整数属性。
此外,变量值不能包含 ASCII NULL
(即 8 位零),因为使用常规的空终止 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
请注意,这不适用于 -=
、/=
等,除非您在算术((( ))
和 $(( ))
)中执行此操作,其中数字已被处理有或没有整数属性都一样。有关这些运算符的完整列表,请参阅 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不使用 +=
赋值运算符来附加字符串,所以你必须这样做:
$ foo=Hello
$ foo="$foo world!"
$ echo "$foo"
Hello world!
这在 bash
中也很好,因此可以认为它是一种更可移植的语法。
答案 29 :(得分:-1)
我还不了解PHP,但这适用于Linux Bash。如果您不想将其影响到变量,可以试试这个:
read pp; *# Assumes I will affect Hello to pp*
pp=$( printf $pp ;printf ' World'; printf '!');
echo $pp;
>Hello World!
您可以放置另一个变量而不是&#39; Hello&#39;或者&#39;!&#39;。你也可以连接更多的字符串。
答案 30 :(得分:-1)
我有点想做一个快速的功能。
#! /bin/sh -f
function combo() {
echo $@
}
echo $(combo 'foo''bar')
另一种给猫皮肤的方法。这次有功能:D
答案 31 :(得分:-4)
您可以尝试以下方式。当替换发生时,双引号将保留空格。
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