Skip to content

3. 매개변수 치환(Parameter Substitution)


변수를 조작하거나 확장시키는 연산은 다음과 같다.


연산 설명
${parameter} 변수인 parameter의 값이란 뜻으로, $parameter와 같음
어떤 문맥에서는 ${parameter}라고 확실히 써 줘야 동작하는 경우가 있음
${parameter-default},
${parameter:-default}
매개변수가 세트되어 있지 않았다면 default를 사용함
:가 있는 경우 매개변수가 선언만 되어 값이 널일 경우에도 기본값을 적용시킴
${parameter=default},
${parameter:=default}
매개변수가 세트되어 있지 않았다면 default를 사용함
:가 있는 경우 매개변수가 선언만 되어 값이 널일 경우에도 기본값을 적용시킴
${parameter+alt_value},
${parameter:+alt_value}
매개변수가 세트되어 있다면 alt_value를 사용하고 아니라면 널 스트링을 사용함
${parameter?err_msg},
${parameter:?err_msg}
매개변수가 세트되어 있다면 그 값을 사용하고 아니라면 err_msg를 출력함


예제) 매개변수 치환과 : 사용하기
#!/bin/bash

# 시스템 환경 변수 확인
# 예를 들어, 콘솔 사용자의 이름을 나타내는
# $USER가 세트되어 있지 않다면
# 시스템은 인식하지 못한다.

# ":"은 ${HOSTNAME?}이 명령어로 실행되는 것을 방지함
# ${HOSTNAME?}이라는 명령어는 없기 때문에
# ":"이 없다면 command not found 에러가 발생함
: ${HOSTNAME?} ${USER?} ${HOME?}
echo "시스템 이름은 ${HOSTNAME} 입니다."
echo "유저 이름은 ${USER} 입니다."
echo "홈 디렉터리는 ${HOME} 입니다."
# 시스템 이름은 SAEMui-MacBookPro-14.local 입니다.
# 유저 이름은 SAEMC 입니다.
# 홈 디렉터리는 /Users/SAEMC 입니다.

# ${variablename?}도 스크립트에서
# 변수가 세트되어 있는지 확인할 수 있다.
ThisVariable=Value-of-ThisVariable

: ${ThisVariable?}
echo "ThisVariable의 값은 ${ThisVariable}."
# ThisVariable의 값은 Value-of-ThisVariable.

ZZXy23AB="HELLO"

# ZZXy23AB에 값이 세트되어 있지 않다면 에러가 발생함
: ${ZZXy23AB?"ZZxy23AB는 세트되지 않았습니다."}

exit 0


변수 길이와 문자열조각을 삭제하는 연산은 다음과 같다.


연산 설명
${#var} $var의 문자 개수이며, 문자열 길이를 의미함
배열의 경우 $(#array)라고 하면 배열의 첫 번째 요소의 길이를 의미함
${#*}${#@}는 위치 매개변수의 개수를 나타냄
배열에 대해 ${#array[*]}${#array[@]}라고 하면 배열 요소의 개수를 나타냄
${var#pattern},
${var##patern}
$pattern$var의 앞 부분과 가장 길거나 가장 짧게 일치하는 부분을 삭제함
${var%pattern},
${var%%pattern}
$pattern$var의 뒷 부분과 가장 길거나 가장 짧게 일치하는 부분을 삭제함


#!/bin/bash

E_NO_ARG=65

if [ "$#" -eq 0 ]; then
    echo "하나 이상의 명령어줄 인자가 필요합니다."
    exit $E_NO_ARG
fi

var01=abcdEFGH28ij

echo "var01 = ${var01}"
# var01 = abcdEFGH28ij
echo "var01의 길이 = ${#var01}"
# var01의 길이 = 12

echo "스크립트로 넘어온 명령어줄 인자 개수 = ${#@}"
echo "스크립트로 넘어온 명령어줄 인자 개수 = ${#*}"

exit 0
#!/bin/bash

var1=abcd12345abc6789

echo "var1 = $var1"
# var1 = abcd12345abc6789
echo "var1 = ${var1}"
# var1 = abcd12345abc6789
echo "${var1}에 들어 있는 글자수 = ${#var1}"
# abcd12345abc6789에 들어 있는 글자수 = 16

pattern1=a*c

# 앞에서부터 가장 짧게 일치하는 3글자 삭제
echo '${var1#$pattern1} =' "${var1#$pattern1}"
# ${var1#$pattern1} = d12345abc6789
# 앞에서부터 가장 길게 일치하는 12글자 삭제
echo '${var1##$pattern1} =' "${var1##$pattern1}"
# ${var1##$pattern1} = 6789

pattern2=b*9

# 뒤에서부터 가장 짧게 일치하는 6글자 삭제
echo '${var1%pattern2} =' "${var1%$pattern2}"
# ${var1%pattern2} = abcd12345a
echo '${var1%%pattern2} =' "${var1%%$pattern2}"
# ${var1%%pattern2} = a

exit 0
#!/bin/bash

# rfe 원래확장자 새확장자
# 예: 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


변수 확장과 문자열조각을 대치하는 연산은 다음과 같다.


연산 설명
${var:pos} 변수 varpos부터 시작하도록 확장
${var:pos:len} 변수 varpos에서 최대 len만큼의 길이를 가지도록 확장
${var/patt/replacement} var에 첫 번째로 일치하는 pattreplacement로 대치시킴
${var//patt/replacement} var에서 일치하는 모든 pattreplacement로 대치시킴
${var/#patt/replacement} var의 접두어(Prefix)가 patt과 일치하면 pattreplacement로 치환
${var/%patt/replacement} var의 접미어(Sufix)가 patt과 일치하면 pattreplacement로 치환
${!varprefix*},
${!varprefix@}
이미 선언된 변수들 중에 varprefix로 시작하는 변수로 확장


#!/bin/bash

var1="abcd-1234-defg"
echo "var1 = $var1"
# var1 = abcd-1234-defg

t=${var1#*-*}
echo "(첫 번째 \"-\"를 포함한 부분까지 잘라냄) var1 = ${t}"
# (첫 번째 "-"를 포함한 부분까지 잘라냄) var1 = 1234-defg

t=${var1##*-*}
echo "(var1에 \"-\"이 들어있다면 빈 문자열을 리턴함) var1 = ${t}"
# (var1에 "-"이 들어있다면 빈 문자열을 리턴함) var1 =

t=${var1%*-*}
echo "(제일 마지막의 \"-\"부터 끝까지 잘라냄) var = ${t}"
# (제일 마지막의 "-"부터 끝까지 잘라냄) var = abcd-1234

path_name="/home/bozo/ideas/thought.for.today"
echo "path_name = $path_name"
# path_name = /home/bozo/ideas/thought.for.today

t=${path_name##/*/}
echo "접두어가 잘린 path_name = ${t}"
# 접두어가 잘려진 path_name = thought.for.today

t=${path_name%/*.*}
echo "접미어가 잘린 path_name = ${t}"
# 접미어가 잘려진 path_name = /home/bozo/ideas

t=${path_name:11}
echo "첫 번째 11개 문자가 잘린 path_name = ${t}"
# 첫 번째 11개 문자가 잘려진 path_name = ideas/thought.for.today

t=${path_name:11:5}
echo "첫 번째 11개 문자가 잘리고 길이가 5인 path_name = ${t}"
# 첫 번째 11개 문자가 잘리고 길이가 5인 path_name = ideas

t=${path_name/bozo/clown}
echo "\"bozo\"가 \"clown\"으로 대치된 path_name = ${t}"
# "bozo"가 "clown"으로 대치된 path_name = /home/clown/ideas/thought.for.today

t=${path_name/today/}
echo "\"today\"가 삭제된 path_name = ${t}"
# "today"가 삭제된 path_name = /home/bozo/ideas/thought.for.

t=${path_name//o/O}
echo "모든 소문자 \"o\"를 대문자로 대치한 path_name = ${t}"
# 모든 소문자 "o"를 대문자로 대치된 path_name = /hOme/bOzO/ideas/thOught.fOr.tOday

t=${path_name//o/}
echo "모든 소문자 \"o\"를 삭제한 path_name = ${t}"
# 모든 소문자 "o"를 삭제한 path_name = /hme/bz/ideas/thught.fr.tday

exit 0
#!/bin/bash

v0="abc1234zip1234abc"
echo "v0 = $v0"
# v0 = abc1234zip1234abc

# 문자열의 접두어에서 일치
v1=${v0/#abc/ABCDEF}
echo "v1 = $v1"
# v1 = ABCDEF1234zip1234abc

# 문자열의 접미어에서 일치
v2=${v0/%abc/ABCDEF}
echo "v2 = $v2"
# v2 = abc1234zip1234ABCDEF

# 문자열의 시작과 끝에서 일치가 일어나야 함
v3=${v0/#123/000}
echo "v3 = $v3"
# v3 = abc1234zip1234abc

v4=${v0/%123/000}
echo "v4 = $v4"
# v4 = abc1234zip1234abc

exit 0
#!/bin/bash

xyz23="whatever"
xyz24=

# 선언된 변수 중 "xyz"로 시작하는 변수로 확장
a=${!xyz*}
echo "a = $a"
# a = xyz23 xyz24

a=${!xyz@}
echo "a = $a"
# a = xyz23 xyz24

exit 0

References