shellscriptで配列を使いたいけど、どうやって扱えば良いかわかりません。
などと言ったシェルスクリプトの配列について難しいという声が多いです。
なので配列の宣言から格納や参照などの基本をまずまとめます。
その後には要素数を数えたり、配列のコピーのやり方など使えるテクニックを現役エンジニアの筆者が教えます。
windowsのプロンプトで使用できるbatやpythonやphpを使用して、業務効率化やWebサイトを作成しております。javaやシェルスクリプトなど、様々なプログラミングを行った実績ありの筆者です。
この記事でシェルスクリプトの配列についての基礎知識や、実際の使い方などを習得する事ができます。
シェルスクリプトで配列の宣言をする
まずは配列の宣言のやり方を見ていきます。
シェルスクリプトで配列の宣言をする方法は「declare -a 配列名」です。
今回は「my_array1」という箱を作成して、配列と宣言します。
declare -a my_array1
- declare -r 変数 ・・・読み取り専用を宣言
- declare -i 変数 ・・・数値を宣言
- declare -A 変数 ・・・連想配列を宣言
シェルスクリプトでの配列の基礎
配列の初期化
まずは配列を初期化します。配列=()とすることで初期化できます。
my_array1=()
これで配列に値が格納されていたとしても、初期化して新しい配列として使用する事ができます。
配列に値を格納する方法
では配列に値を格納します。配列=(値1 値2 値3 . . .)という風に値を入れていきます。
配列に値を格納するには配列の後にスペースなしで「=()」を入力して、()の中に値をスペース区切りで格納していきます。
my_array1=(0 1 2)
今回は「my_array1」という配列に0と1と2を格納しました。
配列の値を参照する方法
では先程、配列に格納した値を参照してみます。
配列の値を参照するには${配列名[インデックス番号]}で可能です。
${my_array1[0]}
これで配列の1番目(インデックス0)の値を参照できます。
実践:配列の値を参照してみる
実際に配列のインデックス0の値をechoコマンドで表示してみます。
my_array1=(0 1 2)
echo ${my_array1[0]}
上のシェルスクリプトを実行してみます。
実行結果は「0」が表示されます。
配列の値を全て参照する方法
配列にどのような値がはいっているか、一括で表示できたら楽だと思いませんか?
配列に入っている値を一括参照するには以下のシェルスクリプトで可能です。
${my_array1[@]}
または
${my_array1[*]}
このスクリプトで配列の全ての値を参照できます。
実践:配列の値を全て参照してみる
実際に配列の全ての値をechoコマンドで表示してみます。
my_array1=(0 1 2)
echo ${my_array1[@]}
上のシェルスクリプトを実行してみます。
0 1 2
結果は全ての値が参照できています。
配列の途中から参照する方法
配列の基礎で全ての値を参照する方法がありましたが、途中から参照する方法もあります。
${my_array1[@]:2}
上のシェルスクリプトの場合は、配列の2番目から後ろの値を参照できます。
実践:配列の途中から参照してみる
実際に配列の途中からの値をechoコマンドで表示してみます。
my_array1=(0 1 2 3 4)
echo ${my_array1[@]:2}
上のシェルスクリプトを実行してみます。
2 3 4
結果は指定した2以降の全ての値が参照できています。
配列のインデックスを参照する方法
配列で値ではなくインデックスを表示する方法もあります。
${!my_array1[@]}
配列名の前に「!」を付ける事でインデックスを参照できます。
実践:配列のインデックスを参照してみる
実際に配列のインデックスをechoコマンドで表示してみます。
my_array1=(zero iti ni)
echo ${!my_array1[@]}
上のシェルスクリプトを実行してみます。
0 1 2
結果は全てのインデックスが参照できています。
実践:配列のインデックスを途中から参照してみる
おまけで配列のインデックスを途中からechoコマンドで表示してみます。
my_array1=(zero iti ni)
echo ${!my_array1[@]:2}
上のシェルスクリプトを実行してみましたが、何も表示されません。
0 1 2
結果的にインデックスは途中から参照する事はできません。
インデックスを使用して配列に値を格納する
インデックスを使用して順番に配列に値を格納する
では配列の好きなインデックスに値を格納してみます。配列名=([0]=値 [1]=値 [2]=値)で可能です。
my_array1=([0]=0 [1]=1 [2]=2)
インデックス0に「0」をインデックス1に「1」を、インデックス2に「2」を入れています。
実践:インデックスを使用して順番に配列に値を格納してみる
実際に配列のインデックスに値を格納してみます。その結果をechoコマンドで表示してみます。
my_array1=([0]=0 [1]=1 [2]=2)
echo ${my_array1[@]}
上のシェルスクリプトを実行してみます。
0 1 2
インデックスに値を格納できています。
インデックスをいくつか飛ばして配列に値を格納する
インデックスをいくつか飛ばして配列に値を格納することもできます。
my_array1=([0]=0 [2]=2 [4]=4)
インデックス0に「0」をインデックス2に「2」を、インデックス4に「4」を入れています。
この時はインデックス1,3には空白が入る事に注意しましょう!
実践:インデックスをいくつか飛ばして配列に値を格納してみる
実際に配列のインデックスにとびとびで値を格納してみます。その結果をechoコマンドで表示してみます。
my_array1=([0]=0 [2]=2 [4]=4)
echo ${my_array1[0]}
echo ${my_array1[1]}
echo ${my_array1[2]}
echo ${my_array1[3]}
echo ${my_array1[4]}
上のシェルスクリプトを実行してみます。
0
2
4
インデックスに値を格納できています。飛ばしたインデックスは空白になっています。
配列の値を上書き格納する方法
配列の値を修正したい場合は、インデックスを指定して値を上書きできます。
実践:配列の値を上書き格納してみる
配列に値を入れています。
my_array1=()
my_array1=([1]=1 [2]=3 [4]=4)
echo ${my_array1[@]}
入っている値を${my_array1[@]}で全表示してみます。
1 3 4
インデックス「2」の値「3」を2に上書き格納します。
my_array1[2]=2
echo ${my_array1[@]}
配列を全表示してみます。
1 2 4
インデックス「2」の値が「3」から「2」に上書き格納されています。
配列の値を削除する方法
配列の値を削除するには「unset 配列[インデックス]」で可能です。
実践:配列の値を削除してみる
my_array1=([0]=0 [1]=1 [2]=2 [3]=fuyo)
echo ${my_array1[@]}
上のシェルスクリプトの配列を全表示してみます。
0 1 2 fuyo
インデックス3に格納している値「fuyo」を削除してみます。
unset my_array1[3]
echo ${my_array1[@]}
配列を全表示してみます。
0 1 2
インデックス3に格納している値「fuyo」が削除されている事がわかります。
配列の要素数を数える方法
配列にはいくつの要素がはいっているか数えたい時がよくあります。
そんな時は${#配列名[@]}で取得できます。
${#my_array1[@]}
実践:配列の要素数を数えてみる
実際に配列の要素数を数えてみます。その結果をechoコマンドで表示してみます。
my_array1=(0 1 2)
echo ${#my_array1[@]}
上のシェルスクリプトを実行してみます。
3
配列の要素数の「3」が表示されています。
少し変わった配列の参照方法
インデックスを指定しない場合は0の値が表示されます。値を参照する方法は「${配列名[インデックス]}」でした。
my_array1=([0]=0 [1]=1 [2]=2)
${my_array1}
インデックスを指定しない${my_array1}には「0」が参照されます。
インデックス0を参照する時にない場合は空白になります。
my_array1=([2]=2 [3]=3 [4]=4)
echo ${my_array1}
インデックス0の値が格納されていないので、${my_array1}は空白になります。
配列の要素をコピーして使用する方法
配列をコピーして別の配列として扱いたい場合もあります。そんな場合は下のシェルスクリプトで可能です。
配列名2=("&{配列名1[@]}")
ややこしいですが、下のように考えたら整理がつきやすいです。
- 配列名2=()で箱を作る
- コピーしたい配列の値を全表示する${配列名1[@]}を「”」で囲んで、箱に入れる
配列の要素をコピーして使用する時の注意点
配列の要素をコピーして使用する時の注意点として、コピーした後はインデックスに空白があればつめられるという事です。
したの例のようにインデックス2は空白の配列があります。
my_array1=([0]=0 [1]=1 [3]=3)
echo ${my_array1[0]}
echo ${my_array1[1]}
echo ${my_array1[2]}
echo ${my_array1[3]}
このシェルスクリプトを実行すると結果は以下です。
0
1
3
インデックス2の値が空白の配列です。
この配列「my_array1」をコピーして配列「my_array2」にコピーします。
my_array2=("${my_array1[@]}")
echo ${my_array2[0]}
echo ${my_array2[1]}
echo ${my_array2[2]}
echo ${my_array2[3]}
今度はこのシェルスクリプトを実行すると結果は以下です。
0
1
3
コピー前の配列のインデックス2の「空白」がコピー後の配列では「3」になっています。
つまり配列の要素をコピーして使用する時はインデックスに空白があれば、つめられるという事です。
配列の要素をコピーし値を追加して配列を作る方法
配列のコピーをして、その配列に値を入れたいです。そのような時は下のシェルスクリプトで可能です。
my_array1=(0 1 2)
my_array2=("${my_array1[@]}" 3 4 5)
先程の配列のコピーのカッコの中に、空白を区切りとして値を格納しています。
実践:配列のコピーをして、その配列に値を入れてみる
実際に配列のコピーをして、その配列に値を入れて、その値をechoコマンドで表示してみます。
my_array1=(0 1 2)
my_array2=("${my_array1[@]}" 3 4 5)
echo ${my_array2[@]}
上のシェルスクリプトを実行してみます。
0 1 2 3 4 5
結果はコピーした配列の要素0,1,2の後に、指定した3,4,5が追加された配列になっています。
同じ配列に値を格納したいのであれば、下のシェルスクリプトで可能です。
my_array1=(0 1 2)
my_array1=("${my_array1[@]}" 3 4 5)
echo ${my_array1[@]}
上のシェルスクリプトを実行してみます。
0 1 2 3 4 5
結果は同じ配列にでも同じやり方で値をコピーして追加格納できています。
また単純に配列に値を入れたいのであれば、下のように「+=」を使用すれば簡単です。
my_array1=(0 1 2)
my_array1+=(3 4 5)
echo ${my_array1[@]}
上のシェルスクリプトを実行してみます。
0 1 2 3 4 5
結果は同じ配列に簡単に追加格納できています。
まとめ:シェルスクリプトで配列の使い方について
シェルスクリプトで配列の宣言をする方法
declare -a 配列名
配列を初期化する方法
配列名=()
配列に値を格納する方法
配列名=(値0 値1 値2 ...)
配列の値を参照する方法
${配列名[インデックス番号]}
配列の値を全て参照する方法
${配列名[@]}
または
${配列名[*]}
配列の値を途中から全て参照する方法
${配列名[@]:位置}
配列のインデックス値を全て参照する方法
${!配列名[@]}
インデックスは途中から参照する事はできません。
インデックスを使用して順番に配列に値を格納する方法
配列名=([インデックス値0]=値0 [インデックス値1]=値1 [インデックス値2]=値2 ...)
配列の値を削除する方法
unset 配列名[インデックス値]
配列の要素数を数える方法
${#配列名[@]}
配列の要素をコピーして使用する方法
配列名2=("&{配列名1[@]}")
配列の要素をコピーして使用する時はインデックスに空白があれば、つめられる。
配列の要素をコピーし値を追加して配列を作る方法
新配列名=("${旧配列名[@]}" 追加する値1 追加する値2 追加する値3 ...)
同じ配列に値を格納したい
配列名=("${配列名[@]}" 追加する値1 追加する値2 追加する値3 ...)
または
配列名+=(追加する値1 追加する値2 追加する値3 ...)
配列は覚える事が沢山ありますが、シェルスクリプトでは必須項目のうちの一つなので、何度も読み直してマスターしてください。