在PHP中,字符串按如下方式连接在一起:
$foo = "Hello";
$foo .= " World";
在这里,$foo变成了“Hello World”。
这是如何在Bash中实现的?
在PHP中,字符串按如下方式连接在一起:
$foo = "Hello";
$foo .= " World";
在这里,$foo变成了“Hello World”。
这是如何在Bash中实现的?
当前回答
我在方便的时候这样做:使用内联命令!
echo "The current time is `date`"
echo "Current User: `echo $USER`"
其他回答
a="Hello,"
a=$a" World!"
echo $a
这是连接两个字符串的方式。
有人对性能表示担忧,但没有提供数据。让我建议一个简单的测试。
(注意:macOS上的日期不提供纳秒,因此必须在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.54432MB。您可以将代码从双倍数据更改为附加一个常量,以获得更精细的图形和故障点。但我认为这应该给你足够的信息来决定你是否在乎。就个人而言,低于100 MB我不会。您的里程数可能有所不同。
先猛击
由于这个问题特别适用于Bash,我的第一部分回答将提出不同的正确做法:
+=:附加到变量
语法+=可以以不同的方式使用:
附加到字符串var+=。。。
(因为我很节俭,我只使用两个变量foo和a,然后在整个答案中重复使用相同的变量。;-)
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+=(…)
我们的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
嗯。这不是一个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:使用内置命令重新构造变量
printf内置命令提供了一种强大的绘制字符串格式的方法。由于这是一个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
注意:使用双引号可能有助于处理包含空格、制表符和/或换行符的字符串
printf -v foo "%s World" "$foo"
立即启动Shell
在POSIX shell下,不能使用bashms,因此没有内置printf。
大体上
但你可以简单地做到:
foo="Hello"
foo="$foo World"
echo $foo
Hello World
格式化,使用分叉打印
如果要使用更复杂的构造,必须使用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
尽管有特殊的运算符+=用于连接,但有一种更简单的方法:
foo='Hello'
foo=$foo' World'
echo $foo
双引号需要额外的计算时间来解释内部变量。如果可能,请避免。
这是通过AWK的:
$ foo="Hello"
$ foo=$(awk -v var=$foo 'BEGIN{print var" World"}')
$ echo $foo
Hello World