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