배열 / 함수

markyang92·2021년 4월 26일
0

shell-script

목록 보기
9/19
post-thumbnail

배열

  • 배열은 POSIX에 정의되어 있지 않음
  • 본 쉘에서는 사용할 수 없음
  • 배열 변수는 export 할 수 없음

생성

1. indexed array

  • idx로 숫자를 사용함
  • declare -A 없이 사용할 수 있음
AA=( 11 "hello world!" 22 )

AA[0]=11
idx=2
AA[idx]=33 # indexed array는 AA[$idx]로 안해도됨
echo ${AA[idx]}

2. associative array

  • idx로 string을 사용할 수 있음
  • declare -A 로 선언해야함
declare -A arr

var=hello
arr=( [zero]=0 [one]=1 [two]=2 [$var]=3 )

echo arr[$var]

  • associative arrary는 추가할 때 꼭 아래와 같이 해야함
#!/bin/bash

declare -A DST
SSH_SERVER="ssh -p 8888 pi@10.100.0.1"

DST+=([0]="${SSH_SERVER}")  <-- [0]="값" 넣는 것 유의!
for ((i=0; i<10; i++)); do
    echo "${DST[$i]}"	   
    echo "${DST[0]}"
done

혹은

DST+=([first]="${SSH_SERVER}")
echo "${DST[first]}"

VAR="first"
echo "${DST[$VAR]}"       

Array 값 조회

현재 쉘이 정의된 모든 array 변수명 보기

compgen -A arrayvar

Array 값 사용

  • 반드시!! { }를 사용해야함
    • 아래와 같이 { } 없으면, $ARR[2] 와 같이하면 $ARR 변수가 먼저 확장되어 DST3[0]으로 확장됨
ARR=(DST1 DST2 DST3)

echo $ARR[2] (x)  --> DST1[2]
echo ${ARR[2]}    --> DST3

@, * 차이

  • " "를 사용하지 않은 ${arr[@]}${arr[*]}는 똑같은 IFS에 의해 단어 분리가된다.
    • "${arr[@]}": 개개의 원소를 " "로 quote
    • "${arr[*]}": 모든 원소를 하나의 " "안에 IFS 변수 값을 구분자로 하여 넣는 것과 같음
출력
"${arr[@]}""${arr[0]}" "${arr[2]}" "${arr[3]}"
"${arr[*]}""${arr[0]X${arr[1]}X${arr[2]}"
사이사이 XIFS 변수 값 중 첫 문자

indexed array

  • index 에서 산술연산이 가능하다.
AA=(11 22 33 44 55)
idx=2

echo ${AA[idx]}  --> 33
echo ${AA[ idx + 1 ]} ---> 44
echo "${AA[ idx == 2 ? 3 : 4 ]}" ---> 44

associative array

  • index 값이 string 이므로 index에 산술연산을 하면 안됨
declare -A CC
CC[$(echo aaa)}=1
CC[ $(echo aaa)}=2
CC[ $(echo aaa) ]=3

-->CC=(["aaa"]=1 [ "aaa"]=2 [ "aaa" ]=3)

표현식

표현식설명
${#array[@]}배열의 전체 원소 갯수
${#array[3]}indexed array 에서 배열의 idx 3 내용의 stirng 길이
${#array[hello]}associative array 에서 배열의 idx = 'hello' 일 경우의 원소 string 길이
${array[@]}array 에서 배열의 전체 원소들 나열
${!array[@]}array 에서 배열의 전체 원소 index들 나열

배열 해제

indexed array

unset "arr[0]" # indexed array인 arr의 0 을 삭제
unset "arr[1]" # indexed array인 arr의 1 을 삭제

associative array

unset "arr[hello]" # associative array에서 idx가 hello인 원소 삭제
var="hello"
unset "arr[$var]"

해제 후, 재참조

AA=(11 22 33 44 55)
unset "AA[2]"
echo ${#AA[@]}
4	                <--- 배열 길이는 반영됨

for line in "${AA[@]}"; do
    echo "$line"
done
11
22
44
55                <--- for문도 정상적으로 동작

echo "${AA[2]}"   <--- 하지만 공백으로 남아있음

방법 1
1. AA=( "${AA[@]}" ) # 재할당

방법 2
1. set -f; IFS='' <--- IFS 값을 null로 설정
2. AA=( ${AA[*] )  <--- quotes를 사용하지 않음
3. set +f; unset IFS

indexed 해제 후, 재참조 예

#!/bin/bash

DST1="'-e ssh -p 8888' mark@myhost.com:/dst1"
DST2="'-e ssh -p 9999' mark2@myhost2.com:/dst2"
DST3="'-e ssh -p 10000' mark3@myhost3.com:/dst3"

DST_LIST=("${DST1}" "${DST2}")
DST_LIST+=("${DST3}")

for line in "${DST_LIST[@]}"; do
    echo "$line"
done

ORIGIN_DST_LIST_LEN=${#DST_LIST[@]}

for ((i=0; i<${ORIGIN_DST_LIST_LEN}; i++)); do
    if [[ "${DST_LIST[i]}" =~ "9999" ]]; then
        unset "DST_LIST[i]"
    fi
done
echo "---------------------------------"
DST_LIST=("${DST_LIST[@]}")

for line in "${DST_LIST[@]}"; do
    echo "$line"
done

echo "LEN: ${#DST_LIST[@]}"
  • 실행결과
'-e ssh -p 8888' mark@myhost.com:/dst1
'-e ssh -p 9999' mark2@myhost2.com:/dst2
'-e ssh -p 10000' mark3@myhost3.com:/dst3
---------------------------------
'-e ssh -p 8888' mark@myhost.com:/dst1
'-e ssh -p 10000' mark3@myhost3.com:/dst3
LEN: 2


값 삽입

append

  1. indexed array
AA+=( 100 )

  1. assosiative array
declare -A AA
AA+=([hello]=0)
AA+=([world]=1)

문자열 split

  1. 여러 줄의 문자열
versions="2.15/                                        
2.16.0.g/                                            
2.16/                                        
2.17.0.g/                                        
2.18.0.g/"
  1. / 을 버리면서 배열로 하나씩 추가
versions_list=($(echo "${versions}" | tr "/" "\n"))
echo "${versions_list[0]}"
------ 출력 -----
2.15

함수

선언

  1. 선언은 뭘 어케해도 상관 X



함수 한줄 사용 시

  • 마지막에 구분자 ; 넣어줘야함

args 사용

  1. 아규먼트$1, $2 식으로 함수 내부에서 사용된다.


  1. 문자열 args스페이스바, 개행 문자주의! scanf 처럼 동작
  • $3: 과 같은 호출 방식으로 문자열은 스페이스바, 개행문자까지만 가져온다.
  • ${STR}: 과 같이 나중에 선언된 변수도 직접 호출가능

args 주의점

  1. 아래와 같이 문자열 결과가 있다고 하자
  2. 아래와 같이 스크립트를 작성하면

    띄워 쓰기 때문에 $1에는 33G만 들어간다.

해결 방법

  • 문자열을 넘길 때는 조심하자
    • "문자열1 문자열2 ... "로 다시 quote로 둘러 싼다.

$# : args 갯수

$@ : args 전체


return

  • return: 함수의 리턴. 정수만 pass 가능
  • $?: 최근 함수의 리턴 정수를 담고 있음


scope

  • 기본적으로 local 선언 안하면 환경변수로 export
profile
pllpokko@alumni.kaist.ac.kr

0개의 댓글