ウェブサイト検索

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 システムでの多くのバックグラウンド スクリプトの開発への道を開きました。