配列の定義方法
括弧内に要素を列挙
最も一般的な定義方法です。要素をスペースで区切って記述します。
nums=(100 200 300 400 500)
echo ${nums[@]}
インデックスを明示して定義
任意のインデックスに値を直接割り当てます。連続している必要はありません。
data=([0]=1 [1]=2 [5]=6)
echo ${data[@]}
変数の展開を利用して定義
文字列として定義したリストを配列に変換します。
str_items="apple banana cherry"
fruits=($str_items)
echo ${fruits[@]}
要素を個別に代入
インデックスごとに別々の行で代入します。
colors[0]="red"
colors[1]="green"
colors[2]="blue"
echo ${colors[@]}
配列の基本操作
要素の参照
特定のインデックスや、配列全体の要素を取得します。インデックスを省略すると最初の要素が返ります。
echo ${fruits} # 最初の要素
echo ${fruits[1]} # インデックス1の要素
echo ${fruits[@]} # 全要素
echo ${fruits[*]} # 全要素
インデックスの一覧取得
変数名の前に!を付けると、値ではなくインデックスのリストを取得できます。
echo ${!fruits[@]}
配列の長さ(要素数)の取得
変数名の前に#を付けると要素数をカウントします。
echo ${#fruits[@]}
配列のスライス(部分抽出)
${配列名[@]:開始位置:個数}の形式で、配列の一部を抽出します。
arr=(10 20 30 40 50)
echo ${arr[@]:2:2} # 30 40
要素の置換
パターンマッチによる置換が可能ですが、元の配列は変更されません。永続的に変更するには再代入が必要です。
vals=(1 2 3 4 5)
echo ${vals[@]/3/99} # 1 2 99 4 5
echo ${vals[@]} # 1 2 3 4 5 (元のまま)
要素の削除
unsetコマンドを使用します。特定の要素か、配列全体を削除できます。
unset vals[2] # インデックス2を削除
unset vals # 配列全体を削除
要素の追加
いくつかの方法で要素を追加できます。
配列名[インデックス]=値配列名[${#配列名[@]}]=値(末尾に追加)配列名=("${配列名[@]}" 値1 値2)(ダブルクォーテーション必須。スペース含む要素の分割を防ぐため)配列名+=(値1 値2)
関数への配列渡し
関数の引数として配列変数をそのまま渡すと、最初の要素しか渡されません。全体を渡すには${配列名[@]}として展開し、関数側で再構成する必要があります。
process_array() {
local reconstructed=("$@")
echo "再構成: ${reconstructed[@]}"
}
items=("first item" "second item" "third item")
process_array "${items[@]}"
応用:配列の疎密判定
配列の要素数と最大インデックスを比較することで、欠落のない完全な(密な)配列かどうかを判定できます。
#!/bin/bash
check_density() {
local arr=("$@")
local len=${#arr[@]}
local max_idx=$((${#arr[@]} - 1))
# 実際の最大インデックスを取得
local actual_max_idx=$(echo ${!arr[@]} | tr ' ' '\n' | sort -n | tail -n 1)
if [ "$max_idx" -eq "$actual_max_idx" ]; then
echo "密な配列です"
else
echo "疎な配列です(欠落あり)"
fi
}
dense=(10 20 30 40)
sparse=([0]=10 [2]=30 [5]=50)
check_density "${dense[@]}"
check_density "${sparse[@]}"
配列のソートアルゴリズム
バブルソート
隣接する要素を比較し、大小関係が逆であれば交換する処理を繰り返すアルゴリズムです。
#!/bin/bash
nums=(5 3 8 1 2)
len=${#nums[@]}
for ((i=0; i<len-1; i++)); do
for ((j=0; j<len-i-1; j++)); do
if [ ${nums[$j]} -gt ${nums[$((j+1))]} ]; then
tmp=${nums[$j]}
nums[$j]=${nums[$((j+1))]}
nums[$((j+1))]=$tmp
fi
done
done
echo ${nums[@]}
選択ソート
基準となる位置の要素とその他の要素を比較し、条件を満たす要素と交換を繰り返すことでソートを行います。バブルソートとは異なり、隣接要素の比較ではなく、指定した位置との比較・交換が行われます。
リバースソート(反転)
配列の先頭と末尾の要素を交換し、中央に向かって順に処理を進めることで要素を反転させます。
#!/bin/bash
items=(a b c d e)
cnt=${#items[@]}
for ((i=0; i<cnt/2; i++)); do
swap=${items[$i]}
items[$i]=${items[$cnt-$i-1]}
items[$cnt-$i-1]=$swap
done
echo ${items[@]}