출처 : https://wiki.kldp.org/HOWTO/html/Adv-Bash-Scr-HOWTO/parameter-substitution.html
변수를 조작하거나 확장시키기
- ${parameter}
변수인 parameter의 값이란 뜻으로서, $parameter라고 한 것과 같습니다. 어떤 문맥에서는 ${parameter}라고 확실히 써 줘야 동작하는 수도 있습니다.
문자열 변수들을 연결할 때 쓰일 수 있습니다.
your_id=${USER}-on-${HOSTNAME}
echo "$your_id"
#
echo "Old \$PATH = $PATH"
PATH=${PATH}:/opt/bin # 스크립트가 도는 동안 $PATH 에 /opt/bin 을 추가.
echo "New \$PATH = $PATH" |
- ${parameter-default}
매개변수가 세트되지 않았다면 default를 사용합니다.
echo ${username-`whoami`}
# $username이 여전히 세트되어 있지 않다면 `whoami`의 결과를 에코. |
참고: 이렇게 하면 ${parameter:-default}라고 하는 것과 거의 비슷하지만 :이 있을 때는 매개변수가 선언만 되어 값이 널일 경우에도 기본값을 적용시킵니다.
#!/bin/bash
username0=
# username0 는 선언만 되고 널로 세트됐습니다.
echo "username0 = ${username0-`whoami`}"
# 에코 되지 않습니다.
echo "username1 = ${username1-`whoami`}"
# username1 는 선언되지 않았습니다.
# 에코 됩니다.
username2=
# username2 는 선언만 되고 널고 세트됐습니다.
echo "username2 = ${username2:-`whoami`}"
# 조건 테스트시 - 가 아니고 :- 를 썼기 때문에 에코 됩니다.
exit 0 |
- ${parameter=default}, ${parameter:=default}
매개변수가 세트 되어 있지 않다면 기본값으로 세트.
두 형태는 거의 비슷하지만 :이 있을 때는 위의 경우처럼 $parameter가 선언만 되고 값이 널일 경우에도 기본값으로 세트 시킨다는 차이점이 있습니다[1]
echo ${username=`whoami`}
# "username" 변수를 `whoami`의 결과로 세트. |
- ${parameter+alt_value}, ${parameter:+alt_value}
매개변수가 세트되어 있다면 alt_value를 쓰고 아니라면 널 스트링을 씁니다.
이 두 형태는 거의 비슷하지만 parameter가 선언되고 널일 경우에 :이 있고 없고의 차이가 나타납니다. 아래를 보세요.
echo "###### \${parameter+alt_value} ########"
echo
a=${param1+xyz}
echo "a = $a" # a =
param2=
a=${param2+xyz}
echo "a = $a" # a = xyz
param3=123
a=${param3+xyz}
echo "a = $a" # a = xyz
echo
echo "###### \${parameter:+alt_value} ########"
echo
a=${param4:+xyz}
echo "a = $a" # a =
param5=
a=${param5:+xyz}
echo "a = $a" # a =
# a=${param5+xyz} 와 결과가 다르죠?
param6=123
a=${param6+xyz}
echo "a = $a" # a = xyz |
- ${parameter?err_msg}, ${parameter:?err_msg}
매개변수가 세트되어 있으면 그 값을 쓰고 아니라면 err_msg를 출력.
두 형태도 역시 비슷하지만 :은 parameter가 선언만 되고 널일 경우에만 차이점이 나타납니다.
예 9-10. 매개변수 치환과 : 쓰기
#!/bin/bash
# 몇개의 시스템 환경 변수 확인
# 예를 들어, 콘솔 사용자의 이름을 나타내는 $USER 가 세트 돼 있지 않다면,
#+ 시스템은 여러분을 인식하지 못합니다.
: ${HOSTNAME?} ${USER?} ${HOME?} ${MAIL?}
echo
echo "시스템 이름은 $HOSTNAME 입니다."
echo "여러분의 이름은 $USER 입니다."
echo "여러분의 홈디렉토리는 $HOME 입니다."
echo "여러분의 메일 INBOX는 $MAIL 에 있습니다."
echo
echo "이 메세지를 읽고 있다면,"
echo "중요한 환경 변수가 세트 되어 있다는 뜻입니다."
echo
echo
# ------------------------------------------------------
# ${variablename?} 도 스크립트에서 변수가 세트 되어 있는지를
#+ 확인할 수 있습니다.
ThisVariable=Value-of-ThisVariable
# 문자열 변수는 변수 이름에 쓸 수 없는 문자가
#+ 세트될 수도 있으니 주의하세요.
: ${ThisVariable?}
echo "ThisVariable 의 값은 $ThisVariable."
echo
echo
: ${ZZXy23AB?"ZZXy23AB 는 세트되지 않았습니다."}
# ZZXy23AB 에 값이 세트되어 있지 않다면,
#+ 에러 메세지를 뿌리고 종료할 것입니다.
# 에러 메세지를 지정할 수 있습니다.
# : ${ZZXy23AB?"ZZXy23AB 는 세트되지 않았습니다."}
# 다음과 똑같은 결과: dummy_variable=${ZZXy23AB?}
# dummy_variable=${ZZXy23AB?"ZXy23AB 는 세트되지 않았습니다."}
#
# echo ${ZZXy23AB?} >/dev/null
echo "위에서 스크립트가 종료됐기 때문에 이 메세지는 안 보입니다."
HERE=0
exit $HERE # 여기서 종료되지 *않습니다*. |
변수 길이/문자열조각(substring) 삭제
- ${#var}
문자열 길이 ($var의 문자 갯수). 배열의 경우에, ${#array}라고 하면 배열의 첫번째 요소의 길이를 알려줍니다.
예 9-11. 변수의 길이
#!/bin/bash
# length.sh
E_NO_ARGS=65
if [ $# -eq 0 ] # 이 스크립트에서는 명령어줄 인자가 필요합니다.
then
echo "하나 이상의 명령어줄 인자가 필요합니다."
exit $E_NO_ARGS
fi
var01=abcdEFGH28ij
echo "var01 = ${var01}"
echo "var01 의 길이 = ${#var01}"
echo "스크립트로 넘어온 명령어줄 인자 갯수 = ${#@}"
echo "스크립트로 넘어온 명령어줄 인자 갯수 = ${#*}"
exit 0 |
- ${var#pattern}, ${var##pattern}
$pattern이 $var의 앞 부분과 가장 길거나 가장 짧게 일치하는 부분을 삭제.
예 A-6에서 발췌한 사용법 예제:
# "days-between.sh" 예제에서 쓰인 함수.
# 주어진 인자의 앞 부분에 들어있는 하나 이상의 0 을 삭제.
strip_leading_zero () # 날짜나 월의 앞 부분에 나오는 0을 삭제하지 않으면
{ # Bash 가 8진수로 해석하기 때문에(POSIX.2, sect 2.9.2.1)
val=${1#0} # 이렇게 해 주는게 좋습니다.
return $val
} |
다른 사용법 예제:
echo `basename $PWD` # 현재 디렉토리의 basename.
echo "${PWD##*/}" # 현재 디렉토리의 basename.
echo
echo `basename $0` # 스크립트 이름.
echo $0 # 스크립트 이름.
echo "${0##*/}" # 스크립트 이름.
echo
filename=test.data
echo "${filename##*.}" # 데이타
# 전체 파일이름에서 확장자. |
- ${var%pattern}, ${var%%pattern}
$pattern이 $var의 뒷 부분과 가장 짧거나 가장 길게 일치하는 부분을 삭제.
Bash 버전 2에는 옵션이 더 늘었습니다.
예 9-12. 매개변수 치환에서의 패턴 매칭
#!/bin/bash
# 매개변수 치환 연산자인 # ## % %% 를 써서 패턴 매칭하기.
var1=abcd12345abc6789
pattern1=a*c # * (와일드 카드)는 a 와 c 사이의 모든 문자와 일치합니다.
echo
echo "var1 = $var1" # abcd12345abc6789
echo "var1 = ${var1}" # abcd12345abc6789 (다른 형태)
echo "${var1} 에 들어 있는 글자수 = ${#var1}"
echo "pattern1 = $pattern1" # a*c ('a'와 'c' 사이의 모든 문자)
echo
echo '${var1#$pattern1} =' "${var1#$pattern1}" # d12345abc6789
# 앞에서부터 가장 짧게 일치하는 3 글자를 삭제 abcd12345abc6789
# ^^^^^^^^^^ |-|
echo '${var1##$pattern1} =' "${var1##$pattern1}" # 6789
# 앞에서부터 가장 길게 일치하는 12 글자를 삭제 abcd12345abc6789
# ^^^^^^^^^^ |----------|
echo; echo
pattern2=b*9 # 'b'와 '9' 사이의 모든 문자.
echo "var1 = $var1" # abcd12345abc6789 를 계속 씁니다.
echo "pattern2 = $pattern2"
echo
echo '${var1%pattern2} =' "${var1%$pattern2}" # abcd12345a
# 뒤에서부터 가장 짧게 일치하는 6 글자를 삭제 abcd12345abc6789
# ^^^^^^^^^^ |----|
echo '${var1%%pattern2} =' "${var1%%$pattern2}" # a
# 뒤에서부터 가장 길게 일치하는 12 글자를 삭제 abcd12345abc6789
# ^^^^^^^^^^ |-------------|
# 이렇게 외우세요.
# # 과 ## 은 문자열의 앞쪽에서부터 동작을 하고,
# % 와 %% 는 뒤쪽에서부터 동작을 합니다.
echo
exit 0 |
예 9-13. 파일 확장자 바꾸기:
#!/bin/bash
# rfe
# ---
# 파일 확장자 바꾸기(Renaming file extensions).
#
# rfe 원래확장자 새확장자
#
# 예제:
# 현재 디렉토리의 *.gif 를 *.jpg 로 바꾸려면,
# rfe gif jpg
ARGS=2
E_BADARGS=65
if [ $# -ne $ARGS ]
then
echo "사용법: `basename $0` 원래확장자 새확장자"
exit $E_BADARGS
fi
for filename in *.$1
# 첫번째 인자로 끝나는 파일 목록을 전부 탐색.
do
mv $filename ${filename%$1}$2
# 첫번째 인자와 일치하는 부분을 떼어내고,
# 두번째 인자를 덧붙임.
done
exit 0 |
변수 확장/문자열조각 대치
여기서 소개하는 것들은 ksh에서 따 온 것입니다.
- ${var:pos}
var 변수가 pos 옵셋부터 시작하도록 확장.
- ${var:pos:len}
변수 var가 pos에서 최대 len만큼의 길이를 갖도록 확장. 이 연산자의 창조적인 사용 예제를 보려면 예 A-9 참고.
- ${var/patt/replacement}
var에 첫번째로 일치하는 patt을 replacement로 대치시킴.
replacement를 안 적으면 patt이 지워짐.
- ${var//patt/replacement}
위의 경우와 비슷하게 replacement를 안 적어주면 모든 patt이 지워짐.
예 9-14. 임의의 문자열을 파싱하기 위해 패턴 매칭 사용하기
#!/bin/bash
var1=abcd-1234-defg
echo "var1 = $var1"
t=${var1#*-*}
echo "var1 (첫번째 - 를 포함한 부분까지 잘라냄) = $t"
# # 이 가장 짧은 문자열과 매치하고 * 가 빈 문자열을 포함한 모든것과
#+ 일치하기 때문에 t=${var1#*-} 도 똑같이 동작합니다.
# (S. C. 가 지적해 주었습니다.)
t=${var1##*-*}
echo "var1에 \"-\" 이 들어있다면 빈 문자열을 리턴함... var1 = $t"
t=${var1%*-*}
echo "var1 (제일 마지막의 - 부터 끝까지 잘라냄) = $t"
echo
# -------------------------------------------
path_name=/home/bozo/ideas/thoughts.for.today
# -------------------------------------------
echo "path_name = $path_name"
t=${path_name##/*/}
echo "접두어가 잘려진 path_name = $t"
# 이 경우에서는 t=`basename $path_name` 이라고 해도 똑같습니다.
# t=${path_name%/}; t=${t##*/} 라고 하는 것이 좀 더 일반적인 해법이지만,
#+ 가끔은 실패할 수도 있습니다.
# $path_name 이 뉴라인으로 끝날 경우에는 `basename $path_name` 은 제대로 동작하지 않겠지만,
#+ 위 표현식은 제대로 동작할 것입니다.
# (Thanks, S.C.)
t=${path_name%/*.*}
# t=`dirname $path_name` 라고 하는 것과 똑같습니다.
echo "접미어가 잘려진 path_name = $t"
# 이렇게 하면 "../", "/foo////", # "foo/", "/" 같은 경우에는 실패할 것입니다.
# basename 은 접미어가 없고 dirname 은 있을 경우에 접미어를 삭제하는 것
#+ 역시 복잡한 문제입니다.
# (Thanks, S.C.)
echo
t=${path_name:11}
echo "첫번째 11개 문자가 잘려나간 $path_name = $t"
t=${path_name:11:5}
echo "첫번째 11개 문자가 잘려나가고 길이가 5인 $path_name = $t"
echo
t=${path_name/bozo/clown}
echo "\"bozo\" 가 \"clown\" 으로 대치된 $path_name = $t"
t=${path_name/today/}
echo "\"today\" 가 삭제된 $path_name = $t"
t=${path_name//o/O}
echo "모든 소문자 o 를 대문자로 만든 $path_name = $t"
t=${path_name//o/}
echo "모든 소문자 o 를 삭제한 $path_name = $t"
exit 0 |
- ${var/#patt/replacement}
var의 접두어(prefix)가 patt과 일치하면 patt을 replacement로 치환.
- ${var/%patt/replacement}
var의 접미어(suffix)가 patt과 일치하면 patt을 replacement로 치환.
예 9-15. 문자열의 접두, 접미어에서 일치하는 패턴 찾기
#!/bin/bash
# 문자열의 접두어/접미어 에서 패턴 치환 하기.
v0=abc1234zip1234abc # 원래 변수.
echo "v0 = $v0" # abc1234zip1234abc
echo
# 문자열의 접두어(시작)에서 일치.
v1=${v0/#abc/ABCDEF} # abc1234zip1234abc
# |-|
echo "v1 = $v1" # ABCDE1234zip1234abc
# |---|
# 문자열의 접미어(끝)에서 일치.
v2=${v0/%abc/ABCDEF} # abc1234zip123abc
# |-|
echo "v2 = $v2" # abc1234zip1234ABCDEF
# |----|
echo
# ----------------------------------------------------
# 문자열의 시작과 끝에서 일치가 일어나야지만
#+ 대치가 일어납니다.
# ----------------------------------------------------
v3=${v0/#123/000} # 일치하지만 시작 부분이 아닙니다.
echo "v3 = $v3" # abc1234zip1234abc
# *대치가 안 일어납니다*.
v4=${v0/%123/000} # 일치하지만 끝 부분이 아닙니다.
echo "v4 = $v4" # abc1234zip1234abc
# *대치가 안 일어납니다*.
exit 0 |
- ${!varprefix*}, ${!varprefix@}
이미 선언된 변수들 중에 varprefix로 시작하는 변수들.
xyz23=whatever
xyz24=
a=${!xyz*} # 선언된 변수중 "xyz"로 시작하는 변수로 확장.
echo "a = $a" # a = xyz23 xyz24
a=${!xyz@} # 위와 같음.
echo "a = $a" # a = xyz23 xyz24
# Bash 2.04 버전에서 이 기능이 추가됨. |