본문

Bash Shell 변수확장변경자, 변수확장자

리눅스 배쉬 셸(Bash Shell)에서는 변수에 특수문자를 포함하는 형태로 문자열 처리를 수행할 수 있다. '김태용의 리눅스 쉘 스크립트 프로그래밍 입문' 책에서는 이들을 변수확장변경자, 변수확장자로 정의하였는데, 영어로는 Parameter Expansion(매개변수 확장) 또는 Parameter Substitution(매개변수 치환)이라고 부르는것 같다. 매개변수라는 용어보다는 변수라는 용어를 자주쓰기때문인지 아니면 이 둘을 구분하지 않기때문에 책에서는 이와같이 해석한것 같은데, 별로 좋은 해석은 아닌것 같다.


참고로, 이름이 비슷한 Variable Substitution(변수 치환)은 현재 코드상에 위치한 변수를 파라미터값으로 치환한다는 의미이고, 모든 코드는 실행시 변수치환이 수행된다 (ex. echo $ten; => echo 10;) 참고로 앞에서 변수와 파라미터라는 단어를 구분해서 사용했는데, 이때 파라미터는 값을 저장하는 저장소의 개념으로, 그리고 변수는 이런 파라미터공간을 reference하는 이름이라는 의미이다. 그런데 아무래도 한국에서는 이를 명확히 구분하지는 않으니까, 이번 글에서는 가끔씩은 구분하고 가끔씩은 혼용할것이다.


이 글을 다 읽고나면 아래 명령이 이해가 될것이다. 리눅스에서 파일 확장자를 일괄적으로 변경하는 명령이고, 리눅스버전만 남겨놓으면 아쉬우니 그 아래에 윈도우(도스)에서 사용할 수 있는 명령도 같이 첨부하였다. (mhtm 확장자 파일을 mhtml 확장자를 갖도록 이름변경)

for f in *.mhtm; do mv ./"$f" "${f%mhtm}mhtml"; done

FOR /R %x IN (*.mhtm) DO ren "%x" *.mhtml


  • 변수사용 기본
variable=VALUE 변수값을 VALUE로 설정한다 (변수에 값을 설정할때는 변수명만 사용하고, 변수값을 사용할때는 변수명앞에 $를 붙인다)
$variable 현재 문자열에서 해당변수를 파라미터값으로 치환한다. (변수 치환)
${variable} 위와 같지만, {}을 사용함으로써 뒤이어오는 문자열과 구분을 할 수 있다.

$ AA=                      # 변수 AA의 값을 널(Null)으로 설정한다
$ AA=cde                 # 변수 AA의 값을 cde로 설정한다
$ echo "ab$AAfg"       # 변수 $AAfg는 설정되지 않았으므로 'ac' 만 echo된다. 
ac
$ echo "ab${AA}fg"     # '{ }' 을 이용하여 $AA와 나머지 문자열을 구분. abcdefg가 echo된다.
abcdefg

  • 변수 확장 변경자
연산자만 사용하는경우: 변수의 설정 여부를 확인
콜론+연산자 사용하는경우: 변수의 설정 여부에 더불어 변수가 Null으로 설정되었는지 확인한다 

${variable-myword} 변수가 설정되지 않은경우 myword로 변수치환을 수행한다
${variable:-myword} 변수가 설정되지 않은경우 또는 Null으로 설정된 경우 myword로 변수치환을 수행한다
${variable=myword} 변수가 설정되지 않은경우 myword를 변수에 대입하고 변수치환을 수행한다
${variable:=myword} 변수가 설정되지 않은경우 또는 Null으로 설정된 경우 myword를 변수에 대입하고 변수치환을 수행한다
${variable+myword} 변수가 설정된 경우 myword로 변수치환을 수행한다.
${variable:+myword} 변수가 설정되고 동시에 Null이외의 값으로 설정된 경우 myword로 변수치환을 수행한다
${variable?errmsg} 변수가 설정된 경우는 $variable로 동작한다. 변수가 설정되지 않은 경우 표준오류출력으로 errmsg를 출력한다. 
${variable:?errmsg} 변수가 Null이외의 값으로 설정된 경우 $variable로 동작한다. 이외의 경우(변수가 설정되지 않았거나, Null으로 설정된 경우) errmsg를 출력하고 쉘을 종료한다. errmsg를 생략하게 되면 parameter null or not set이라는 메세지가 출력된다.
${variable:offset} offset에서 시작하여 변수 variable의 부분 문자열을 출력한다 offset은 0에서 시작하여 문자열의 끝까지다.
${variable:offset:length} offset에서 시작하여 length 만큼의 부분 문자열을 변수 variable의 값에서 추출한다.

$ AA=hello
$ echo ${AA:-linux}        # AA 에 값이 있으면 AA 값을 사용한다
hello
$ echo ${AA-linux}
hello
$ unset AA
$ echo ${AA:-linux}        # AA 가 unset 되어 없는 상태이므로 값은 linux 가 된다. 
linux
$ echo ${AA-linux}
linux
$ AA=""
$ echo ${AA:-linux}       # ':-' 는 null 은 값이 없는것으로 보고 linux 를 사용한다.
linux
$ echo ${AA-linux}        # '-' 는 null 도 값으로 취급하기 때문에 아무것도 표시되지 않는다.
--------------------------------------------------
AA=""
$ echo ${AA:-linux}
linux
$ echo $AA             # ':-' 는 AA 변수에 값을 대입하지 않는다.
$ echo ${AA:=linux}
linux
$ echo $AA             # ':=' 는 AA 변수에 값을 대입한다.
linux
--------------------------------------------------
$ AA=hello
$ echo ${AA:+linux}       # AA 에 값이 있으므로 대체값 linux 를 사용한다.
linux
$ echo ${AA+linux}
linux
$ AA=""
$ echo ${AA:+linux}       # ':+' 는 null 은 값으로 취급하지 않기 때문에 null 을 리턴한다.
$ echo ${AA+linux}        # '+' 는 null 도 값으로 취급하기 때문에 대체값 linux 를 사용한다.
linux
$ unset AA
$ echo ${AA:+linux}       # 변수가 존재하지 않으므로 null 을 리턴한다.
$ echo ${AA+linux}
--------------------------------------------------
$ AA=hello
$ echo ${AA:?null or not set}      # AA 에 값이 있으므로 AA 값을 사용한다
hello
$ echo ${AA?not set}
hello
$ AA=""
$ echo ${AA:?null or not set}       # ':?' 는 null 은 값으로 취급하지 않기 때문에
bash: AA: null or not set           # error message 를 출력하고 $? 값으로 1 을 리턴한다 
$ echo $?
1
$ echo ${AA?not set}                # '?' 는 null 도 값으로 취급하기 때문에 아무것도 표시되지 않는다.
$ unset AA
$ echo ${AA:?null or not set}       # 변수가 존재하지 않는 상태이므로 
bash: AA: null or not set           # 모두 error message 를 출력 후 종료한다.
$ echo $?
1
$ echo ${AA?not set}
bash: AA: not set
$ echo $?
1
$ echo ${AA?}                        # error message 는 생략할 수 있다.
bash: AA: parameter null or not set
--------------------------------------------------
$ AA="Arch Linux Ubuntu Fedora"
$ echo ${AA:11}
Ubuntu Fedora
$ echo ${AA:11:6}
Ubuntu
$ echo ${AA:(-6)}
Fedora
$ echo ${AA:(-6):2}
Fe
$ echo ${AA:(-6):-2}
Fedo

  • 변수 확장자 (Parameter Expansion)
${variable%pattern} variable 값의 후반부에서 패턴과 일치하는 가장 작은 부분을 찾아 제거
${variable%%pattern} variable 값의 후반부에서 패턴과 일치하는 가장 큰 부분을 찾아 제거
${variable#pattern} variable 값의 전반부에서 패턴과 일치하는 가장 작은 부분을 찾아 제거
${variable##pattern} variable 값의 전반부에서 패턴과 일치하는 가장 큰 부분을 찾아 제거
${#variable} 변수의 문자수로 치환. 
${variable/pattern/string} 첫번째 pattern에 맞는 부분이 string으로 변경된다. string부분을 지정하지 않으면 해당 문자열을 제거
${variable//pattern/string} pattern에 맞는 모든 부분이 string으로 변경된다. string부분을 지정하지 않으면 해당 문자열을 제거
${variable/#pattern/string} 앞에서부터 첫번째 pattern에 맞는 부분이 string으로 변경된다. 
${variable/%pattern/string} 뒤에서부터 첫번째 pattern에 맞는 부분이 string으로 변경된다.

$ AA="this.is.a.inventory.tar.gz"
$ echo ${AA#*.}               # 앞에서 부터 shortest match
is.a.inventory.tar.gz
$ echo ${AA##*.}              # 앞에서 부터 longest match
gz
$ echo ${AA%.*}               # 뒤에서 부터 shortest match
this.is.a.inventory.tar
$ echo ${AA%%.*}              # 뒤에서 부터 longest match
this
$ AA="/home/bash/bash_hackers.txt"
$ echo ${AA%/*}               # 디렉토리 부분 구하기
/home/bash
$ echo ${AA##*/}              # 파일명 부분 구하기
bash_hackers.txt
$ AA="hello world"
$ echo ${#AA}
11
--------------------------------------------------
$ AA="Arch Linux Ubuntu Linux Fedora Linux"
$ echo ${AA/Linux/Unix}               # Arch Linux 만 바뀌였다.
Arch Unix Ubuntu Linux Fedora Linux
$ echo ${AA//Linux/Unix}              # Linux 가 모두 Unix 로 바뀌였다
Arch Unix Ubuntu Unix Fedora Unix
$ echo ${AA/Linux}                    # 바꾸는 스트링을 주지 않으면 매칭되는 부분이 삭제된다.
Arch Ubuntu Linux Fedora Linux Suse Linux
$ echo ${AA//Linux}                  
Arch Ubuntu Fedora Suse
$ echo ${AA/#Linux/XXX}               # '#Linux' 는 맨 앞 단어를 의미
XXX Ubuntu Linux Fedora Linux
$ echo ${AA/%Linux/XXX}               # '%Linux' 는 맨 뒤 단어를 의미
Linux Ubuntu Linux Fedora XXX


댓글

Holic Spirit :: Tistory Edition

design by tokiidesu. powerd by kakao.