웹사이트 검색

Linux 셸 스크립팅에서 배열 작업 – 8부


배열 개념이 없는 프로그래밍 언어는 상상할 수 없습니다. 다양한 언어에서 어떻게 구현되는지는 중요하지 않습니다. 대신 배열은 유사하거나 다른 데이터를 하나의 기호 이름으로 통합하는 데 도움이 됩니다.

여기에서 쉘 스크립팅에 대해 관심을 갖고 있으므로 이 기사는 이러한 배열 개념을 활용하는 일부 쉘 스크립트를 가지고 놀아보는 데 도움이 될 것입니다.

어레이 초기화 및 사용

최신 버전의 bash에서는 1차원 배열을 지원합니다. 배열은 쉘 내장 선언을 통해 명시적으로 선언될 수 있습니다.


declare -a var  

하지만 위와 같이 배열변수를 선언할 필요는 없습니다. 다음과 같이 개별 요소를 배열에 직접 삽입할 수 있습니다.


var[XX]=<value>

여기서 'XX'는 배열 인덱스를 나타냅니다. 배열 요소를 역참조하려면 중괄호 구문을 사용하세요.


${var[XX]}

참고: 배열 색인은 항상 0으로 시작합니다.

전체 배열을 초기화하는 또 다른 편리한 방법은 아래와 같이 괄호 쌍을 사용하는 것입니다.


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

위의 스크립트는 자명하기 때문에 자세히 설명하는 것은 의미가 없다고 생각합니다. 필요하다면 이 시리즈의 한 부분을 문자열 조작에만 전념하겠습니다.

배열로 명령 대체

명령 대체는 명령 또는 여러 명령의 출력을 다른 컨텍스트에 할당합니다. 여기 배열의 맥락에서 우리는 명령의 출력을 배열의 개별 요소로 삽입할 수 있습니다. 구문은 다음과 같습니다.


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 시스템에서 많은 백그라운드 스크립트 개발의 길을 열었습니다.