bash - script - shell variable in string
如何在Bash中連接字符串變量 (19)
在PHP中,字符串連接在一起如下:
$foo = "Hello";
$foo .= " World";
在這裡, $foo
成為“Hello World”。
如何在Bash中完成?
Bash第一
由於這個問題專門針對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
:使用builtin命令重構變量
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
注意:使用雙引號可能對操作包含spaces
, tabulations
newlines
和/或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
Bash還支持+ =運算符,如以下腳本所示:
$ A="X Y"
$ A+="Z"
$ echo "$A"
X YZ
以下是大多數答案所討論的簡明摘要。
假設我們有兩個變量:
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, 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行)
也可以看看:
你也可以這樣做:
$ var="myscript"
$ echo $var
myscript
$ var=${var}.sh
$ echo $var
myscript.sh
又一種方法......
> 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
如果您要做的是將字符串拆分為多行,則可以使用反斜杠:
$ a="hello\
> world"
$ echo $a
helloworld
中間有一個空格:
$ a="hello \
> world"
$ echo $a
hello world
這個也只增加了一個空格:
$ a="hello \
> world"
$ echo $a
hello world
引號最簡單的方法:
B=Bar
b=bar
var="$B""$b""a"
echo "Hello ""$var"
您可以在沒有引號的情況下連接。 這是一個例子:
$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
我想從列表中構建一個字符串。 無法找到答案,所以我在這裡發布。 這是我做的:
list=(1 2 3 4 5)
string=''
for elm in "${list[@]}"; do
string="${string} ${elm}"
done
echo ${string}
然後我得到以下輸出:
1 2 3 4 5
我更喜歡使用大括號${}
來擴展字符串中的變量:
foo="Hello"
foo="${foo} World"
echo $foo
> Hello World
捲曲括號適合連續字符串使用:
foo="Hello"
foo="${foo}World"
echo $foo
> HelloWorld
否則使用foo = "$fooWorld"
將無法正常工作。
我有點像快速功能。
#! /bin/sh -f
function combo() {
echo [email protected]
}
echo $(combo 'foo''bar')
另一種給貓皮膚的方法。 這次有功能:D
我還不了解PHP,但這適用於Linux Bash。 如果您不想將其影響到變量,可以嘗試這樣做:
read pp; *# Assumes I will affect Hello to pp*
pp=$( printf $pp ;printf ' World'; printf '!');
echo $pp;
>Hello World!
你可以放置另一個變量而不是'Hello'或'!'。 您也可以連接更多字符串。
更安全的方式:
a="AAAAAAAAAAAA"
b="BBBBBBBBBBBB"
c="CCCCCCCCCCCC"
d="DD DD"
s="${a}${b}${c}${d}"
echo "$s"
AAAAAAAAAAAABBBBBBBBBBBBCCCCCCCCCCCCDD DD
包含空格的字符串可以成為命令的一部分,使用“$ XXX”和“$ {XXX}”來避免這些錯誤。
另外看看關於+ =的其他答案
請注意,這不起作用
foo=HELLO
bar=WORLD
foobar=PREFIX_$foo_$bar
因為它似乎放棄了$ foo並離開你:
PREFIX_WORLD
但這會奏效:
foobar=PREFIX_"$foo"_"$bar"
並留下正確的輸出:
PREFIX_HELLO_WORLD
這是通過AWK的一個:
$ foo="Hello"
$ foo=$(awk -v var=$foo 'BEGIN{print var" World"}')
$ echo $foo
Hello World
bla=hello
laber=kthx
echo "${bla}ohai${laber}bye"
會輸出
helloohaikthxbye
當$blaohai
導致變量未找到錯誤時,這很有用。 或者如果字符串中有空格或其他特殊字符。 "${foo}"
正確地逃脫了你投入的任何東西。
foo="Hello "
foo="$foo World"
var1='hello'
var2='world'
var3=$var1" "$var2
echo $var3