[Shell Script] 배열(array)과 Map 사용하기

2021. 7. 12. 22:25Linux

반응형

Shell script 에서도 배열과 map 자료구조를 사용할 수 있다.

최근에 회사에서 shell script 를 통해 특정 리스트의 통계를 내야해서 map 구조가 필요했었는데 이렇게 쓸 수 있다니 너무나 유용했다.

 

 

개발 환경

bash 버전 : 5.1.8 

bash 버전은 bash --version 을 통해 확인할 수 있다.

 

bash 버전별로 명령어가 안먹히는 경우가 있으니 참고할 것 !!!!!

나의 경우에는, 처음에 map 기능을 사용하려고 하는데, bash 버전이 낮아 자꾸 원하는대로 되지 않았다. 엉엉. 관련해서는 아래 map 섹션에서 자세히 설명하겠다. 

 

 

배열(array)

아래와 같이 사용할 수 있다. 

# 기본 문법
변수=(값1 값2 값3 그외 쭉쭉)

# 예시
array=(V1 V2 V3 V4 V5)

또는 아래처럼 생성할 수도 있다.

array2=()

array2+=(V1)
array2+=(V2)
array2+=(V3)

echo $array2

# 결과 : V1 V2 V3

 

배열의 크기

크기도 알아야지.

arraySize=${#array[@]}

echo $arraySize

# 결과 : 5

 

배열 empty 여부 체크

배열이 비었는지 체크해야지!

if [ ${#array[@]} -eq 0 ]; then
	echo "array 비었다"
fi

 

 

배열과 for 문

배열을 쓰는데 for 문을 안쓸 수 없겠죵?

 

👉 array 의 index 로 접근할 때

lastIndex=$(expr ${#array[@]} - 1)
for i in {0..$lastIndex}; do
	echo "i : $i"
done

# 결과 👇
# i : 1
# i : 2
# i : 3
# i : 4
# i : 5

 

👉 array 의 값(value) 로 접근할 때

for value in $array; do
    echo "value : $value"
done

# 또는
for value in "${array[@]}"; do
    echo "value : $value"
done

# 결과 👇
# value : V1
# value : V2
# value : V3
# value : V4
# value : V5

 

Tip. grep 등의 명령어(command)의 결과값을 배열로 담을 수 있다.

# 기본 문법
변수=($(명령어))

# 간단 예시
command_result=($(ls))

# 출력 결과 : 현재 경로에 있는 모든 파일 리스트가 출력될 것이다.

 

예시 - grep 명령어를 사용해보자.

grep_result_list=($(grep -oh 'nuri' ./testFile.txt ))

 

위 코드의 의미는,

  • grep -oh 'nuri' ./testFile.txt : testFile.txt 에서 'nuri' 라는 단어를 찾아 매칭되는 것들만 출력해준다.
  • grep_result_list=($(grep ~~~)) : 위에서 찾은 결과값들을 배열 형식으로 grep_result_list 변수에 담아준다. 즉, grep_result_list 는 배열이 된다.

 

 

Map 사용하기

Shell script 에서도 key-value 형식의 map 구조를 사용할 수 있다 !!!

# 기본 문법
declare -A 변수

변수[key]=value


# 예시
declare -A map

map[key1]=value1
map[key2]=value2

echo $map
# 출력 결과 : value1 value2

 

Map 크기

배열과 동일!

mapSize=${#map[@]}

 

Map 에 특정 key 값이 존재하는지 체크

예를 들어, map 에 key3 가 존재하는지 알고 싶다!

여기서 사용하는 -z 옵션은 문자열이 null(빈 문자열)이면 true 를 반환하는 아이.

if [ -z ${map[key3]} ]; then
    echo "key3 not exist"
else
    echo "key3 exist"
fi

 

 

Map과 for 문

map을 쓰는데 for 문을 안쓸 수 없겠죵?

for key in ${!map[@]}; do
    value=${key}
    echo "key:$key, value:$value"
done

# 출력 결과 👇
# key:key1, value:key1
# key:key2, value:key2

 

 

Trouble Shooting. bash 버전이 낮아서 map 을 사용할 수가 없어..

TL;DR : 명령어가 기대한 대로 동작하지 않으면 bash 버전을 확인하고 업데이트 해보는 것을 추천한다.

 

map 을 사용하기 위해 declare -A map 을 스크립트에서 돌리는데,, 자꾸 -A 라는 옵션을 사용할 수가 없데... ㅠㅠㅠㅠ 왜왜.. 뭐가 문젠데 ㅠㅠ 구글링에서는 다 이렇게 쓰라는데 왜 안되는데,,

 

삽질) -A 라는 옵션을 쓸 수 없다고 하니,, -a 를 써보니 오? 되네 ?!!! 

결과) map 기능은 쓸 수 있으나.. key-value 를 추가하면 계속 최신에 추가한 값만 남아있음. 즉, 값을 추가해도 계속 사이즈가 1이야..

 

그러던 중, bash 버전에 따라 명령어가 안 먹는 경우가 있다는 글을 보고,, bash 버전을 쳐봤더니 3점대였다. (정확히 기억은 안나는데.. 2버전대였나..?)

하여튼 그래서 bash 를 brew install bash 를 통해 최신 버전으로 업데이트 해줬다. (현재 5.1.8)

 

Wow..... 된다 !!!!! declare -A map 이 된다!!!!! 끼얏 !!!!!!!

 

 

 

 

반응형