Linux シェル スクリプトでの配列の操作 – パート 8
配列の概念なしにプログラミング言語を想像することはできません。さまざまな言語間でどのように実装されるかは問題ではありません。代わりに、配列は、類似または異なるデータを 1 つのシンボル名の下に統合するのに役立ちます。
ここではシェル スクリプトについて説明しますが、この記事は、配列の概念を利用するいくつかのシェル スクリプトを試すのに役立ちます。
配列の初期化と使用法
新しいバージョンの bash では、1 次元配列がサポートされます。配列は、 シェル組み込み関数 declare によって明示的に宣言できます。
declare -a var
ただし、上記のように配列変数を宣言する必要はありません。次のように、個々の要素を配列に直接挿入できます。
var[XX]=<value>
ここで、「XX」は配列のインデックスを表します。配列要素を逆参照するには、中括弧構文を使用します。
${var[XX]}
注: 配列のインデックス付けは常に 0 から始まります。
配列全体を初期化するもう 1 つの便利な方法は、以下に示すように括弧のペアを使用することです。
var=( element1 element2 element3 . . . elementN )
配列に値を割り当てる別の方法もあります。この初期化方法は、前に説明した方法のサブカテゴリです。
array=( [XX]=<value> [XX]=<value> . . . )
また、 シェル組み込み読み取りを使用して、実行中に配列に値を読み取り/代入することもできます。
read -a array
スクリプト内で上記のステートメントを実行すると、何らかの入力を待ちます。配列要素をスペースで区切って (キャリッジ リターンではなく) 指定する必要があります。値を入力した後、Enter キーを押して終了します。
配列要素を横断するために、for ループを使用することもできます。
for i in “${array[@]}”
do
#access each element as $i. . .
done
次のスクリプトは、この特定のセクションの内容を要約したものです。
#!/bin/bash
array1[0]=one
array1[1]=1
echo ${array1[0]}
echo ${array1[1]}
array2=( one two three )
echo ${array2[0]}
echo ${array2[2]}
array3=( [9]=nine [11]=11 )
echo ${array3[9]}
echo ${array3[11]}
read -a array4
for i in "${array4[@]}"
do
echo $i
done
exit 0
配列に対するさまざまな操作
標準的な文字列操作の多くは配列に対して機能します。配列に対するいくつかの操作 (文字列操作を含む) を実装する次のサンプル スクリプトを見てください。
#!/bin/bash
array=( apple bat cat dog elephant frog )
#print first element
echo ${array[0]}
echo ${array:0}
#display all elements
echo ${array[@]}
echo ${array[@]:0}
#display all elements except first one
echo ${array[@]:1}
#display elements in a range
echo ${array[@]:1:4}
#length of first element
echo ${#array[0]}
echo ${#array}
#number of elements
echo ${#array[*]}
echo ${#array[@]}
#replacing substring
echo ${array[@]//a/A}
exit 0
以下は、上記のスクリプトを実行したときに生成される出力です。
apple
apple
apple bat cat dog elephant frog
apple bat cat dog elephant frog
bat cat dog elephant frog
bat cat dog elephant
5
5
6
6
Apple bAt cAt dog elephAnt frog
上記のスクリプトは一目瞭然なので詳しく説明することに意味はないと思います。必要に応じて、このシリーズの 1 つのパートを文字列操作だけに特化します。
配列を使用したコマンド置換
コマンド置換は、1 つまたは複数のコマンドの出力を別のコンテキストに割り当てます。この配列のコンテキストでは、コマンドの出力を配列の個々の要素として挿入できます。構文は次のとおりです。
array=( $(command) )
デフォルトでは、空白で区切られたコマンド出力の内容が個別の要素として配列に挿入されます。次のスクリプトは、755 のアクセス許可を持つファイルであるディレクトリの内容を一覧表示します。
#!/bin/bash
ERR=27
EXT=0
if [ $# -ne 1 ]; then
echo "Usage: $0 <path>"
exit $ERR
fi
if [ ! -d $1 ]; then
echo "Directory $1 doesn't exists"
exit $ERR
fi
temp=( $(find $1 -maxdepth 1 -type f) )
for i in "${temp[@]}"
do
perm=$(ls -l $i)
if [ `expr ${perm:0:10} : "-rwxr-xr-x"` -eq 10 ]; then
echo ${i##*/}
fi
done
exit $EXT
2 次元配列のシミュレーション
1 次元配列を使用して 2 次元行列を簡単に表現できます。行列の各行の行優先順表現では、行列の各行の要素が配列インデックスに順次格納されます。 mXn 行列の場合、同じ式は次のように記述できます。
matrix[i][j]=array[n*i+j]
2 つの行列を追加し、結果の行列を出力する別のサンプル スクリプトを見てください。
#!/bin/bash
read -p "Enter the matrix order [mxn] : " t
m=${t:0:1}
n=${t:2:1}
echo "Enter the elements for first matrix"
for i in `seq 0 $(($m-1))`
do
for j in `seq 0 $(($n-1))`
do
read x[$(($n*$i+$j))]
done
done
echo "Enter the elements for second matrix"
for i in `seq 0 $(($m-1))`
do
for j in `seq 0 $(($n-1))`
do
read y[$(($n*$i+$j))]
z[$(($n*$i+$j))]=$((${x[$(($n*$i+$j))]}+${y[$(($n*$i+$j))]}))
done
done
echo "Matrix after addition is"
for i in `seq 0 $(($m-1))`
do
for j in `seq 0 $(($n-1))`
do
echo -ne "${z[$(($n*$i+$j))]}\t"
done
echo -e "\n"
done
exit 0
シェル スクリプト内で配列を実装する場合には制限がありますが、いくつかの状況、特にコマンド置換を使用する場合には便利です。管理的な観点から見ると、配列の概念は、GNU/Linux システムでの多くのバックグラウンド スクリプトの開発への道を開きました。