3219

PHPでは、文字列は次のように連結されます。

$foo = "Hello";
$foo .= " World";

ここで、$foo「HelloWorld」になります。

これはBashでどのように達成されますか?

4

30 に答える 30

4389
foo="Hello"
foo="${foo} World"
echo "${foo}"
> Hello World

一般に、2つの変数を連結するには、次々に変数を記述します。

a='Hello'
b='World'
c="${a} ${b}"
echo "${c}"
> Hello World
于 2010-11-15T05:41:36.770 に答える
1269

Bashは、+=次のコードに示すように演算子もサポートしています。

A="X Y"
A+=" Z"
echo "$A"

出力

XYZ

于 2010-11-15T08:33:24.583 に答える
1043

最初にBash

この質問は特にBashを表すため、回答の最初の部分では、これを適切に行うためのさまざまな方法を紹介します。

+=:変数に追加

構文+=はさまざまな方法で使用できます。

文字列に追加var+=...

(私は質素なので、2つの変数のみを使用fooaてから、回答全体で同じものを再利用します。;-)

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!>

Stack Overflowの質問構文の使用:

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
于 2013-08-04T10:04:37.863 に答える
138

あなたもこれを行うことができます:

$ var="myscript"

$ echo $var

myscript


$ var=${var}.sh

$ echo $var

myscript.sh
于 2011-10-28T03:09:38.833 に答える
126
bla=hello
laber=kthx
echo "${bla}ohai${laber}bye"

出力します

helloohaikthxbye

$blaohai これは、変数が見つからないというエラーが発生する場合に役立ち ます。または、文字列にスペースやその他の特殊文字がある場合。"${foo}"あなたがそれに入れたものはすべて適切に逃げます。

于 2013-07-25T15:48:20.060 に答える
50
foo="Hello "
foo="$foo World"

     

于 2010-11-15T05:44:10.817 に答える
39

これは、ほとんどの回答が話していることの簡潔な要約です。

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

いくつかの注意:

  • 割り当てのRHSを二重引用符で囲むことは、多くの場合非常にオプションですが、一般的には良い習慣です。
  • +=特にループ内で大きな文字列が少しずつ作成されている場合は、パフォーマンスの観点から優れています。
  • 変数名の前後を使用{}して、それらの展開を明確にします(上の表の行2のように)。{}3行目と4行目に見られるように、変数がシェル変数名の有効な最初の文字である文字(アルファベットまたはアンダースコア)で始まる文字列と連結されていない限り、必要はありません。

参照:

于 2017-12-06T04:04:34.083 に答える
35

私が問題を解決する方法はただです

$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
于 2014-03-07T16:43:07.200 に答える
32
$ a=hip
$ b=hop
$ ab=$a$b
$ echo $ab
hiphop
$ echo $a$b
hiphop
于 2010-11-15T05:42:09.320 に答える
20

さらに別のアプローチ...

> H="Hello "
> U="$H""universe."
> echo $U
Hello universe.

...そしてさらにもう1つ。

> H="Hello "
> U=$H"universe."
> echo $U
Hello universe.
于 2013-03-18T08:24:46.480 に答える
19

アンダースコアのようなものを追加する場合は、エスケープ(\)を使用します

FILEPATH=/opt/myfile

これは機能しませ

echo $FILEPATH_$DATEX

これは正常に機能します。

echo $FILEPATH\\_$DATEX
于 2013-09-20T19:15:27.370 に答える
16

引用符を使用する最も簡単な方法:

B=Bar
b=bar
var="$B""$b""a"
echo "Hello ""$var"
于 2016-12-21T15:23:16.280 に答える
15

+ =演算子が現在許可されている場合でも、2004年にBash3.1で導入されました。

古いバージョンのBashでこの演算子を使用するスクリプトは、運が良ければ「コマンドが見つかりません」エラー、または「予期しないトークンの近くの構文エラー」で失敗します。

下位互換性を気にする人は、選択した回答に記載されているような、古い標準のBash連結方法を使用してください。

foo="Hello"
foo="$foo World"
echo $foo
> Hello World
于 2014-11-04T19:57:34.607 に答える
14

引用符なしで連結できます。次に例を示します。

$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
于 2010-11-15T07:40:15.563 に答える
14

${}文字列内の変数を展開するために中括弧を使用することを好みます。

foo="Hello"
foo="${foo} World"
echo $foo
> Hello World

中括弧は、連続文字列の使用に適合します。

foo="Hello"
foo="${foo}World"
echo $foo
> HelloWorld

そうしないと、を使用foo = "$fooWorld"できません。

于 2017-06-14T05:35:20.803 に答える
8

文字列を複数の行に分割しようとしている場合は、バックスラッシュを使用できます。

$ a="hello\
> world"
$ echo $a
helloworld

間に1つのスペースがある:

$ a="hello \
> world"
$ echo $a
hello world

これはまた、間に1つのスペースのみを追加します。

$ a="hello \
>      world"
$ echo $a
hello world
于 2012-04-03T23:22:10.990 に答える
8

連結のための特別な演算子にもかかわらず+=、より簡単な方法があります。

foo='Hello'
foo=$foo' World'
echo $foo

二重引用符は、内部の変数の解釈に余分な計算時間を要します。可能であれば避けてください。

于 2019-09-18T06:28:18.270 に答える
7

より安全な方法:

a="AAAAAAAAAAAA"
b="BBBBBBBBBBBB"
c="CCCCCCCCCCCC"
d="DD DD"
s="${a}${b}${c}${d}"
echo "$s"
AAAAAAAAAAAABBBBBBBBBBBBCCCCCCCCCCCCDD DD

スペースを含む文字列はコマンドの一部になる可能性があります。これらのエラーを回避するには、「$XXX」と「${XXX}」を使用してください。

さらに、 +=に関する他の回答を見てください

于 2014-02-26T23:39:04.497 に答える
7

注意が必要な特定のケースが1つあります。

user=daniel
cat > output.file << EOF
"$user"san
EOF

"daniel"san必要に応じて、出力しますが、出力しdanielsanません。この場合、代わりに次のことを行う必要があります。

user=daniel
cat > output.file << EOF
${user}san
EOF
于 2015-10-28T17:35:47.760 に答える
6
a="Hello,"
a=$a" World!"
echo $a

これは、2つの文字列を連結する方法です。

于 2019-03-05T19:35:35.990 に答える
5

" World"元の文字列に追加する例として、次のようになります。

#!/bin/bash

foo="Hello"
foo=$foo" World"
echo $foo

出力:

Hello World
于 2015-04-24T05:07:45.297 に答える
5
var1='hello'
var2='world'
var3=$var1" "$var2 
echo $var3
于 2017-02-07T08:50:05.217 に答える
5

パフォーマンスについて懸念が表明されていますが、データは提供されていません。簡単なテストを提案させてください。

(注:datemacOSではナノ秒が提供されないため、これは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未満ではありません。あなたのマイレージは異なる場合があります。

于 2017-12-18T23:56:05.463 に答える
5

リストから文字列を作成したかったのです。その答えが見つからなかったので、ここに投稿します。これが私がしたことです:

list=(1 2 3 4 5)
string=''

for elm in "${list[@]}"; do
    string="${string} ${elm}"
done

echo ${string}

次に、次の出力が得られます。

1 2 3 4 5
于 2018-10-21T10:06:41.923 に答える
3

これは機能しないことに注意してください

foo=HELLO
bar=WORLD
foobar=PREFIX_$foo_$bar

$ fooをドロップするようで、次のようになります。

PREFIX_WORLD

しかし、これは機能します:

foobar=PREFIX_"$foo"_"$bar"

正しい出力を残します。

PREFIX_HELLO_WORLD

于 2013-12-30T20:23:04.140 に答える
2

これがAWKによるものです:

$ foo="Hello"
$ foo=$(awk -v var=$foo 'BEGIN{print var" World"}')
$ echo $foo
Hello World
于 2014-08-24T11:09:58.730 に答える
2

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ないので、より移植性の高い構文と見なすことができます。

于 2021-06-10T12:16:54.763 に答える
1

便利なときにこのようにします。インラインコマンドを使用してください。

echo "The current time is `date`"
echo "Current User: `echo $USER`"
于 2014-01-10T00:26:34.097 に答える
0

私の意見では、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
于 2019-07-09T04:08:53.557 に答える
-1

ちょっとした機能を作るのが好きです。

#! /bin/sh -f
function combo() {
    echo $@
}

echo $(combo 'foo''bar')

猫の皮を剥ぐさらに別の方法。今回は関数付き:D

于 2014-09-08T07:44:57.203 に答える