如何连接Bash中的stringvariables?
在PHP中,string连接在一起,如下所示:
$foo = "Hello"; $foo .= " World";
在这里, $foo
变成了“Hello World”。
这在Bash中是如何完成的?
foo="Hello" foo="$foo World" echo $foo > Hello World
一般来说,要连接两个variables,你可以把它们一个接一个地写出来:
a='hello' b='world' c=$a$b echo $c > helloworld
Bash也支持+ =运算符,如下面的logging所示:
$ A="XY" $ A+="Z" $ echo "$A" X YZ
首先打
由于这个问题特别针对Bash ,我的答案的第一部分将以不同的方式正确地做到这一点:
+=
:追加到variables
语法+=
可以以不同的方式使用:
附加到stringvar+=...
(因为我很节俭,所以我只会使用两个variablesfoo
和a
,然后在整个答案中重复使用.-)
a=2 a+=4 echo $a 24
使用堆栈溢出问题语法,
foo="Hello" foo+=" World" echo $foo Hello World
工作正常!
追加到一个整数((var+=...))
variablesa
是一个string,也是一个整数
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
请注意,在圆括号之间,有一个空格分隔的数组 。 如果你想在你的数组中存储一个包含空格的string,你必须把它们包含在内:
a+=(one word "hello world!" ) bash: !": event not found
嗯.. 这不是一个错误,而是一个function …为了防止bash试图发展!"
,你可以:
a+=(one word "hello world"! 'hello world!' $'hello world\041') declare -pa declare -aa='([0]="36" [1]="18" [2]="one" [3]="word" [4]="hello world!" [5]="h ello world!" [6]="hello world!")'
printf
:使用内build命令重新构造variables
printf
内置命令提供了一种绘制string格式的强大方法。 由于这是一个Bash 内build的 ,所以可以select将格式化的string发送到variables而不是在stdout
上打印:
echo ${a[@]} 36 18 one word hello world! hello world! hello world!
这个数组中有七个string 。 所以我们可以build立一个包含七个位置参数的格式化string:
printf -va "%s./.%s...'%s' '%s', '%s'=='%s'=='%s'" "${a[@]}" echo $a 36./.18...'one' 'word', 'hello world!'=='hello world!'=='hello world!'
或者我们可以使用一个参数格式的string,这将重复许多参数submited …
请注意,我们的a
仍然是一个数组! 只有第一个元素被改变了!
declare -pa declare -aa='([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下,当你访问一个variables名而不指定索引时,你总是只处理第一个元素!
所以要检索我们的七场数组,我们只需要重新设置1st元素:
a=36 declare -pa declare -aa='([0]="36" [1]="18" [2]="one" [3]="word" [4]="hello world!" [5]="he llo world!" [6]="hello world!")'
一个带有许多参数的参数格式string传递给:
printf -va[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
注意:使用双引号可能对于处理包含spaces
, tabulations
newlines
和/或newlines
string很有用
printf -v foo "%s World" "$foo"
现在壳牌
在POSIX shell下,你不能使用bashisms ,所以没有内置的 printf
。
基本上
但是你可以简单地做:
foo="Hello" foo="$foo World" echo $foo Hello World
格式化,使用分叉的 printf
如果你想使用更复杂的结构,你必须使用一个分支 (新的subprocess来完成这个工作,并通过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
你也可以这样做:
$ var="myscript" $ echo $var myscript $ var=${var}.sh $ echo $var myscript.sh
bla=hello laber=kthx echo "${bla}ohai${laber}bye"
会输出
helloohaikthxbye
当$blaohai
导致一个variables未发现的错误时,这是有用的。 或者如果您的string中有空格或其他特殊字符。 "${foo}"
正确地逃脱了你放入它的任何东西。
foo="Hello " foo="$foo World"
我想解决问题的方法就是这样
$a$b
例如,
a="Hello" b=" World" c=$a$b echo "$c"
生产
Hello World
例如,如果尝试连接另一个string的string,
a="Hello" c="$a World"
那么echo "$c"
就会产生
Hello World
有一个额外的空间。
$aWorld
不像你想象的那样工作,但是
${a}World
产生
HelloWorld
$ a=hip $ b=hop $ ab=$a$b $ echo $ab hiphop $ echo $a$b hiphop
又一种方法…
> H="Hello " > U="$H""universe." > echo $U Hello universe.
…还有另一个。
> H="Hello " > U=$H"universe." > echo $U Hello universe.
如果你想附加下划线,使用escape(\)
FILEPATH=/opt/myfile
这不起作用:
echo $FILEPATH_$DATEX
这工作正常:
echo $FILEPATH\\_$DATEX
你可以连接而不用引号。 这里是一个例子:
$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
即使+ =运算符现在被允许,它在2004年被引入Bash 3.1 。
如果你幸运的话,任何在旧Bash版本上使用这个操作符的脚本都会失败,并且会出现“找不到命令”的错误,或者出现“意外标记附近的语法错误”。
对于那些关心向后兼容性的人来说,坚持使用旧的标准Bash连接方法,就像select的答案中提到的那样:
foo="Hello" foo="$foo World" echo $foo > Hello World
我更喜欢使用大括号${}
来扩展string中的variables:
foo="Hello" foo="${foo} World" echo $foo > Hello World
大括号将适合连续string的用法:
foo="Hello" foo="${foo}World" echo $foo > HelloWorld
否则使用foo = "$fooWorld"
将不起作用。
更安全的方式:
a="AAAAAAAAAAAA" b="BBBBBBBBBBBB" c="CCCCCCCCCCCC" d="DD DD" s="${a}${b}${c}${d}" echo "$s" AAAAAAAAAAAABBBBBBBBBBBBCCCCCCCCCCCCDD DD
包含空格的string可以成为命令的一部分,使用“$ XXX”和“$ {XXX}”来避免这些错误。
另外看看关于+ =的其他答案
有一个特别的情况,你应该保重:
user=daniel cat > output.file << EOF "$user"san EOF
将输出"daniel"san
danielsan
,而不是danielsan
,你可能会想要的。 在这种情况下,你应该这样做:
user=daniel cat > output.file << EOF ${user}san EOF
如果你想要做的是将一个string分成几行,你可以使用反斜杠:
$ a="hello\ > world" $ echo $a helloworld
在一个空间之间:
$ a="hello \ > world" $ echo $a hello world
这个也只增加了一个空间:
$ a="hello \ > world" $ echo $a hello world
如果它是你添加" World"
到原始string的例子,那么它可以是:
#!/bin/bash foo="Hello" foo=$foo" World" echo $foo
输出:
Hello World
最简单的方式用引号:
B=Bar b=bar var="$B""$b""a" echo "Hello ""$var"
var1='hello' var2='world' var3=$var1" "$var2 echo $var3
请注意,这是行不通的
foo=HELLO bar=WORLD foobar=PREFIX_$foo_$bar
因为它似乎放弃$ foo并留下:
PREFIX_WORLD
但是这将工作:
foobar=PREFIX_"$foo"_"$bar"
并留下正确的输出:
PREFIX_HELLO_WORLD
我这样做的时候方便:使用内联命令!
echo "The current time is `date`" echo "Current User: `echo $USER`"
这是通过AWK的一个:
$ foo="Hello" $ foo=$(awk -v var=$foo 'BEGIN{print var" World"}') $ echo $foo Hello World
我有点喜欢做一个快速的function。
#! /bin/sh -f function combo() { echo $@ } echo $(combo 'foo''bar')
还有另一种方法来剥皮猫。 这次与function:D
你可以尝试下面的方法。 当replace发生时,双引号将保留空格。
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