Bashでインデックスを指定せずに新しい要素を配列に追加する


回答:


1540

はいあります:

ARRAY=()
ARRAY+=('foo')
ARRAY+=('bar')

Bashリファレンスマニュアル

代入ステートメントがシェル変数または配列インデックス(配列を参照)に値を代入しているコンテキストでは、「+ =」演算子を使用して、変数の以前の値に追加または追加できます。


21
これはbash 3.2.48(OS X 10.8.2)で問題なく動作します。これARRAYは実際の変数名のプレースホルダーにすぎないことに注意してください。あなたの配列のインデックスがある場合でもないシーケンシャル、と追加すると+=、単純に最高のインデックス+ 1に割り当てる
mklement0

3
bashバージョン4.2.24(1)にそのようなものはありますか?
Ali Ismayilov

195
ARRAY + =( 'foo')は、ARRAY + = 'foo'とはかなり異なることに注意することが重要です。ARRAY+ = 'foo'は、最も低い(?)キーを持つエントリに文字列 'foo'を追加します。
TheConstructor 2013年

8
wiki.bash-hackers.org/scripting/bashchangesによると、この構文は最初にバージョン3.1-alpha1で登場しました。
David Yaw

39
@Jas:配列全体にアクセスするには、以下を使用する必要があります。${myarray[@]}スカラーのように配列変数を参照することは、要素0にアクセスすることと同じです。つまり$myarray、と同じ${myarray[0]}です。
mklement0

76

ダムGuyは指摘し、それは、配列は0から始まり、シーケンシャルであるかどうかに注意することが重要です。隣接していないインデックスに割り当てを行ったり、設定を解除したりできるので${#array[@]}、配列の最後にある次のアイテムが常にあるとは限りません。

$ array=(a b c d e f g h)
$ array[42]="i"
$ unset array[2]
$ unset array[3]
$ declare -p array     # dump the array so we can see what it contains
declare -a array='([0]="a" [1]="b" [4]="e" [5]="f" [6]="g" [7]="h" [42]="i")'
$ echo ${#array[@]}
7
$ echo ${array[${#array[@]}]}
h

最後のインデックスを取得する方法は次のとおりです。

$ end=(${!array[@]})   # put all the indices in an array
$ end=${end[@]: -1}    # get the last one
$ echo $end
42

これは、配列の最後の要素を取得する方法を示しています。あなたはしばしばこれを見るでしょう:

$ echo ${array[${#array[@]} - 1]}
g

ご覧のとおり、ここではスパース配列を扱っているため、これは最後の要素ではありません。ただし、これはスパース配列と連続配列の両方で機能します。

$ echo ${array[@]: -1}
i

3
素晴らしいもの; サブストリング抽出構文が配列にも適用できることを知りませんでした。試行錯誤によって決定されるルールは次のとおりです(bash 3.2.48):${array[@]: start[:count]}count elemsを返します。または、指定されていない場合は、残りのすべて要素。次のelemから開始します。-start> = 0の場合:elemから。インデックスが> = startである。-start <0の場合:elemから。そのインデックスは(最後の配列インデックス+ 1)-abs(start); 警告:abs(start)>(last array index + 1)の場合、null文字列が返されます。countを指定すると、インデックスが最初から連続していない場合でも、同じ数の要素が返されます。
mklement0 2012

3
@mklement:Bash 4.2では、負の配列添え字を使用して、配列の末尾から数えた要素にアクセスできます。${array[-1]}
追って通知があるまで一時停止。

知っておくと良いです、ありがとう。OS X(10.8.2以降)は引き続き3.2.48を使用し、stackoverflow.com / questions / 10418616 / …は、残念ながら、「Appleはライセンスされたコードを出荷していないため、かなり古いバージョンのBashを使用しています。 GPL3の下で。」
mklement0 2012

49
$ declare -a arr
$ arr=("a")
$ arr=("${arr[@]}" "new")
$ echo ${arr[@]}
a new
$ arr=("${arr[@]}" "newest")
$ echo ${arr[@]}
a new newest

8
e-t172で説明されている+ =演算子のセマンティクスをサポートしないbashバージョンに最適
akostadinov

12
下位互換性のある優れたソリューションですが、既存の要素のいずれかにスペースがある場合、それらは複数の要素に分割されることに注意してください。arr=("${arr[@]}" "new")スペースのある要素がある場合に使用します
kbolino 2013年

1
これを使用して、アレイの前にプッシュすることもできます。これは私が必要とするものです。
トマーシュZato -復活モニカ

29

配列が常にシーケンシャルであり、0から始まる場合、これを行うことができます。

array[${#array[@]}]='foo'

# gets the length of the array
${#array_name[@]}

等号の間に誤ってスペースを使用した場合:

array[${#array[@]}] = 'foo'

次に、次のようなエラーが表示されます。

array_name[3]: command not found

5
はい、できますが、+=構文(E-T172の答え@参照)である()単純、および(b)には、非連続的である、および/または0で始まっていない配列で動作します
mklement0

正直に言うと、このソリューション(私にとって)は「+ =」よりもうまく機能します。後者では長さが時々間違っている(1つの要素を追加すると2増える)...なので、私はこの返信を好む!:)
Pierpaolo Cira 2017

これは、以前+=に追加されたbashの以前のバージョンでも機能します(例:バージョン2
Zoey Hewll

1
これは、要素にスペースがある場合にも機能します- $arr += ($el)文字列をスペースで分割し、各要素を追加するように見えました。
最大

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.