【bash】シェルの配列について

スポンサーリンク

シェル (bash) の配列について使い方をまとめてみました。

配列を生成する

配列を生成する場合は配列名=(値1 値2 値3)と記述します。値を指定しなかった場合は空の配列が作成されます。

$ arr=()   # 空の配列
$ arr=("first" "second" "third")
$ echo "${arr[@]}"
first second third

declare -a 配列名コマンドを使うことで明示的に宣言することもできます。

$ declare -a arr=("first" "second" "third")
$ echo "${arr[@]}"
first second third

配列名[インデックス]=値という記法が使われた場合も配列が生成されます。

$ arr[0]="first"
$ arr[1]="second"
$ arr[2]="third"
$ echo "${arr[@]}"
first second third

また、生成する時に配列名[1]=値だけを使った場合、インデックス1 にのみ値が入った配列が生成されます。

$ arr[1]="second"
$ echo "${arr[0]}, ${arr[1]}, ${arr[2]}"
, second,

配列を参照する

インデックスは0から始まります。配列を扱う際は中括弧 { } で囲むようにしましょう。インデックスを指定しない場合は、先頭(インデックスが0 )の値のみが出力されます。全ての値を出力する場合はインデックスに「@」を指定します。

$ echo ${arr[0]}   # インデックス0の値
first
$ echo ${arr[2]}   # インデックス2の値
third

$ echo $arr   # 先頭の値のみ
first

$ echo ${arr[@]}   # 全ての値
first second third

配列の要素に値を設定する場合は配列名[インデックス]=値と記述します。

$ arr[0]="hoge"
$ arr[1]="fuga"
$ echo ${arr[@]}
hoge fuga third

配列に要素を追加する

配列に要素を追加する場合は配列名+=(値)と記述します。複数の値を一度に追加することも可能です。

$ arr=("first" "second" "third")
$ arr+=("hoge")
$ echo ${arr[@]}
first second third hoge

$ arr+=("foo" "bar")
$ echo ${arr[@]}
first second third hoge foo bar

括弧を付けなかった場合は最初の要素に文字列として追加されてしまうので気を付けましょう。

$ arr+="hoge"
$ echo ${arr[@]}
firsthoge second third

配列を削除する

配列を削除したい場合はunset 配列名[インデックス]を使用します。

$ unset arr[1]   # インデックス1 の要素を削除
$ unset arr[@]   # 全要素の削除
$ unset arr   # 全要素の削除

要素を削除してもインデックスはそのままです。インデックスを詰める場合は配列を生成し直します。

$ arr=("first" "second" "third")
$ unset arr[2]
$ echo "${arr[0]}, ${arr[1]}, ${arr[2]}"
first, , third   # インデックスはそのまま

$ arr=("${arr[@]}")
$ echo "${arr[0]}, ${arr[1]}, ${arr[2]}"
first, third,   # インデックスが詰められた

配列の全要素・要素数を参照する

配列のインデックスに「@」または「*」を指定すると全ての要素をスペース区切りで出力します。

$ arr=("first" "second" "third")
$ echo ${arr[@]}
first second third

$ echo ${arr[*]}
first second third

要素数を調べたい時は変数の前に「#」を付けて配列の全要素を参照します。

$ echo ${#arr[@]}
3

$ echo ${#arr[*]}
3

@(アットマーク)と*(アスタリスク)の違い

配列の全要素を参照する「@」と「*」の違いは「"(ダブルクォート)」で括った時にでてきます。

特に影響があるのはfor文を使用した時です。まずは「@」の場合です。

arr=("first" "second" "third")
for i in "${arr[@]}"; do
  echo $i
done

# 実行結果
first
second
third

次は「*」の場合です。

arr=("first" "second" "third")
for i in "${arr[*]}"; do
  echo $i
done

# 実行結果
first second third

これを見ても分かる通り、「*」の場合は一回でループが終了しています。ダブルクォートで括った配列のインデックスを「*」で指定すると配列全体の一つの値として展開されてしまうからです。「@」の場合は個々の要素がダブルクォートで括られた状態で展開してくれます。

#「@」を使用した場合のイメージ
for i in "first" "second" "third";

#「*」を使用した場合のイメージ
for i in "first second third";

じゃあ、ダブルクォートで括らなければいいじゃなかと言えばそうでもありません。要素の中にスペースが含まれていた場合に1つの要素が2つの要素と解釈されてしまうからです。

arr=("first" "sec one" "third")
for i in ${arr[*]}; do
  echo $i
done

# 実行結果
first
sec
ond
third

という訳でfor文に配列を使う時は「@」を使用してダブルクォートで括りましょう。

arr=("first" "sec one" "third")
for i in "${arr[@]}"; do
  echo $i
done

# 実行結果
first
sec ond
third

参考サイト

 配列 - Man page of BASH

 bash 配列まとめ - Qiita

参考書籍

入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界
ブルース ブリン
ソフトバンククリエイティブ
売り上げランキング: 95,987