PHPでは、文字列は次のように連結されます。
$foo = "Hello";
$foo .= " World";
ここで、$foo
「HelloWorld」になります。
これはBashでどのように達成されますか?
PHPでは、文字列は次のように連結されます。
$foo = "Hello";
$foo .= " World";
ここで、$foo
「HelloWorld」になります。
これはBashでどのように達成されますか?
foo="Hello"
foo="${foo} World"
echo "${foo}"
> Hello World
一般に、2つの変数を連結するには、次々に変数を記述します。
a='Hello'
b='World'
c="${a} ${b}"
echo "${c}"
> Hello World
Bashは、+=
次のコードに示すように演算子もサポートしています。
A="X Y"
A+=" Z"
echo "$A"
出力
XYZ
この質問は特にBashを表すため、回答の最初の部分では、これを適切に行うためのさまざまな方法を紹介します。
+=
:変数に追加構文+=
はさまざまな方法で使用できます。
var+=...
(私は質素なので、2つの変数のみを使用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
、1つの要素のみの配列です。
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!' $'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!
この配列には7つの文字列があります。したがって、正確に7つの位置引数を含むフォーマットされた文字列を作成できます。
printf -v a "%s./.%s...'%s' '%s', '%s'=='%s'=='%s'" "${a[@]}"
echo $a
36./.18...'one' 'word', 'hello world!'=='hello world!'=='hello world!'
または、送信された引数の数だけ繰り返される1つの引数フォーマット文字列を使用することもできます...
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では、インデックスを指定せずに変数名にアクセスすると、常に最初の要素のみをアドレス指定します。
したがって、7つのフィールド配列を取得するには、最初の要素をリセットするだけで済みます。
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!")'
多くの引数が渡される1つの引数フォーマット文字列:
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
printf -v foo "%s World" "$foo"
POSIXシェルでは、 bashismを使用できなかったため、組み込み はありませんprintf
。
しかし、あなたは簡単に行うことができます:
foo="Hello"
foo="$foo World"
echo $foo
Hello World
printf
より洗練された構造を使用したい場合は、フォーク(ジョブを作成して結果を返す新しい子プロセス)を使用する必要がありますstdout
。
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
あなたもこれを行うことができます:
$ var="myscript"
$ echo $var
myscript
$ var=${var}.sh
$ echo $var
myscript.sh
bla=hello
laber=kthx
echo "${bla}ohai${laber}bye"
出力します
helloohaikthxbye
$blaohai
これは、変数が見つからないというエラーが発生する場合に役立ち
ます。または、文字列にスペースやその他の特殊文字がある場合。"${foo}"
あなたがそれに入れたものはすべて適切に逃げます。
foo="Hello "
foo="$foo World"
これは、ほとんどの回答が話していることの簡潔な要約です。
2つの変数があり、$1が「1」に設定されているとします。
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行目に見られるように、変数がシェル変数名の有効な最初の文字である文字(アルファベットまたはアンダースコア)で始まる文字列と連結されていない限り、必要はありません。参照:
私が問題を解決する方法はただです
$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
$ a=hip
$ b=hop
$ ab=$a$b
$ echo $ab
hiphop
$ echo $a$b
hiphop
さらに別のアプローチ...
> H="Hello "
> U="$H""universe."
> echo $U
Hello universe.
...そしてさらにもう1つ。
> H="Hello "
> U=$H"universe."
> echo $U
Hello universe.
アンダースコアのようなものを追加する場合は、エスケープ(\)を使用します
FILEPATH=/opt/myfile
これは機能しません:
echo $FILEPATH_$DATEX
これは正常に機能します。
echo $FILEPATH\\_$DATEX
引用符を使用する最も簡単な方法:
B=Bar
b=bar
var="$B""$b""a"
echo "Hello ""$var"
+ =演算子が現在許可されている場合でも、2004年にBash3.1で導入されました。
古いバージョンのBashでこの演算子を使用するスクリプトは、運が良ければ「コマンドが見つかりません」エラー、または「予期しないトークンの近くの構文エラー」で失敗します。
下位互換性を気にする人は、選択した回答に記載されているような、古い標準のBash連結方法を使用してください。
foo="Hello"
foo="$foo World"
echo $foo
> Hello World
引用符なしで連結できます。次に例を示します。
$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
${}
文字列内の変数を展開するために中括弧を使用することを好みます。
foo="Hello"
foo="${foo} World"
echo $foo
> Hello World
中括弧は、連続文字列の使用に適合します。
foo="Hello"
foo="${foo}World"
echo $foo
> HelloWorld
そうしないと、を使用foo = "$fooWorld"
できません。
文字列を複数の行に分割しようとしている場合は、バックスラッシュを使用できます。
$ a="hello\
> world"
$ echo $a
helloworld
間に1つのスペースがある:
$ a="hello \
> world"
$ echo $a
hello world
これはまた、間に1つのスペースのみを追加します。
$ a="hello \
> world"
$ echo $a
hello world
連結のための特別な演算子にもかかわらず+=
、より簡単な方法があります。
foo='Hello'
foo=$foo' World'
echo $foo
二重引用符は、内部の変数の解釈に余分な計算時間を要します。可能であれば避けてください。
より安全な方法:
a="AAAAAAAAAAAA"
b="BBBBBBBBBBBB"
c="CCCCCCCCCCCC"
d="DD DD"
s="${a}${b}${c}${d}"
echo "$s"
AAAAAAAAAAAABBBBBBBBBBBBCCCCCCCCCCCCDD DD
スペースを含む文字列はコマンドの一部になる可能性があります。これらのエラーを回避するには、「$XXX」と「${XXX}」を使用してください。
さらに、 +=に関する他の回答を見てください
注意が必要な特定のケースが1つあります。
user=daniel
cat > output.file << EOF
"$user"san
EOF
"daniel"san
必要に応じて、出力しますが、出力しdanielsan
ません。この場合、代わりに次のことを行う必要があります。
user=daniel
cat > output.file << EOF
${user}san
EOF
a="Hello,"
a=$a" World!"
echo $a
これは、2つの文字列を連結する方法です。
" World"
元の文字列に追加する例として、次のようになります。
#!/bin/bash
foo="Hello"
foo=$foo" World"
echo $foo
出力:
Hello World
var1='hello'
var2='world'
var3=$var1" "$var2
echo $var3
パフォーマンスについて懸念が表明されていますが、データは提供されていません。簡単なテストを提案させてください。
(注:date
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になったことを示しています。コードをデータの2倍から定数の追加に変更して、より詳細なグラフと障害点を取得できます。しかし、これはあなたが気にするかどうかを決定するのに十分な情報をあなたに与えるはずだと思います。個人的には、100MB未満ではありません。あなたのマイレージは異なる場合があります。
リストから文字列を作成したかったのです。その答えが見つからなかったので、ここに投稿します。これが私がしたことです:
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
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
bashの変数と配列(インデックス付きまたは連想*)は、デフォルトでは常に文字列ですが、declare
組み込みのフラグを使用して、「整数」(-i
)や「参照」**(-n
)などの属性を指定して、方法を変更できます。振る舞う。
Bash演算は、入力にASCII /文字列番号を受け入れるため、実際に整数属性を使用する理由はほとんどありません。
また、変数値にはASCII NULL
(つまり、8ビットゼロ)を含めることはできません。これは、通常のnullで終了するC文字列を使用して変数を実装するためです。
*つまり、1つ以上のキーと値のペア。
**参照変数は、ラベルが参照変数に割り当てられている別の変数の値に展開されます
文字列を追加します。
$ foo=Hello
$ foo+=' world!'
$ echo "$foo"
Hello world!
$ num=3
$ num+=4
echo "$num"
34 # Appended string (not a sum)
integer属性を使用するいくつかの理由の1つは、+=
代入演算子の動作を変更することです。
$ declare -i num=3
$ num+=4
echo "$num"
7 # Sum
これは、整数属性の有無にかかわらず、数値がすでに同じように扱われている算術(および)内で実行しない限り、、など-=
では機能しないことに注意してください。これらの演算子の完全なリストについては、の「算術評価」のセクションを参照してください。これらの演算子は、Cの場合と同じです。/=
(( ))
$(( ))
man bash
+=
代入演算子を使用して、インデックス付き配列(別名「リスト」)に新しい要素を追加することもできます。
$ foo=(one)
$ foo+=(two)
$ printf 'Separate element: %s\n' "${foo[@]}"
Separate element: one
Separate element: two
これを行う別の一般的な方法は、カウンターを使用することです。
$ foo[c++]=one
$ foo[c++]=two
POSIXシェルは、文字列を追加するために代入演算子を使用しない+=
ため、次のようにする必要があります。
$ foo=Hello
$ foo="$foo world!"
$ echo "$foo"
Hello world!
これも問題bash
ないので、より移植性の高い構文と見なすことができます。
便利なときにこのようにします。インラインコマンドを使用してください。
echo "The current time is `date`"
echo "Current User: `echo $USER`"
私の意見では、2つの文字列を連結する最も簡単な方法は、それを実行する関数を作成してから、その関数を使用することです。
function concat ()
{
prefix=$1
suffix=$2
echo "${prefix}${suffix}"
}
foo="Super"
bar="man"
concat $foo $bar # Superman
alien=$(concat $foo $bar)
echo $alien # Superman
ちょっとした機能を作るのが好きです。
#! /bin/sh -f
function combo() {
echo $@
}
echo $(combo 'foo''bar')
猫の皮を剥ぐさらに別の方法。今回は関数付き:D