본문 바로가기
C.W.K.
Stream
Lesson 02 of 05 · published

매개변수 확장 심화

~13 min · parameter-expansion, default, substitute

Level 0창 구경꾼
0 XP0/95 lessons0/14 achievements
0/100 XP to next level100 XP to go0% complete

두고두고 쓰는 매개변수 확장

bash와 zsh는 변수 값을 읽으면서 기본값, 길이, 잘라내기, 치환을 수행하는 매개변수 확장을 제공해. 외부 프로세스를 띄우지 않고 간단한 조작을 할 수 있지만 두 셸의 세부 확장이 모두 같지는 않아.

기본값

  • ${var:-default}var가 설정되지 않았거나 비어 있으면 default를 사용해.
  • ${var:=default}는 같은 조건에서 기본값을 사용하면서 변수에도 할당해.
  • ${var:+alt}var가 설정되어 있고 비어 있지 않을 때만 alt를 사용하고, 그렇지 않으면 빈 값을 내.
  • ${var:?error}var가 설정되지 않았거나 비어 있으면 오류를 내고 종료하므로 필수 환경 변수를 검사할 때 유용해.

길이

${#var}                    # 문자열 길이
${#arr[@]}                 # 배열 길이

부분 문자열 잘라내기

${var:5}                  # 다섯 번째 글자부터 끝까지
${var:5:3}                # 다섯 번째부터 글자 3개
${var: -4}                # 마지막 글자 4개 (공백 주의!)

앞쪽 패턴을 잘라 내기

  • ${var#prefix}는 앞쪽에서 일치하는 가장 짧은 글로브 패턴을 제거해.
  • ${var##prefix}는 앞쪽에서 일치하는 가장 긴 글로브 패턴을 제거해.
path=/usr/local/bin
echo ${path#*/}            # usr/local/bin
echo ${path##*/}           # bin             (basename!)

뒤쪽 패턴을 잘라 내기

  • ${var%suffix}는 뒤쪽에서 일치하는 가장 짧은 글로브 패턴을 제거해.
  • ${var%%suffix}는 뒤쪽에서 일치하는 가장 긴 글로브 패턴을 제거해.
file=foo.tar.gz
echo ${file%.gz}           # foo.tar
echo ${file%%.*}           # foo

치환

  • ${var/from/to}는 처음 일치하는 패턴 하나를 바꿔.
  • ${var//from/to}는 일치하는 패턴을 모두 바꿔.
  • ${var/#from/to}는 값의 시작에서 일치할 때만 바꿔.
  • ${var/%from/to}는 값의 끝에서 일치할 때만 바꿔.

대소문자

${var^^}                  # 대문자 (bash 4+)
${var,,}                  # 소문자
${var^}                   # 첫 글자만 대문자

외부 명령 없이 작은 변환 처리하기

매개변수 확장은 현재 셸 안에서 처리되므로 작은 반복에서 외부 명령 호출을 줄일 수 있어. 그래도 복잡한 변환을 한 줄에 압축해 읽기 어려워진다면 sed, awk, Python처럼 의도가 드러나는 도구가 더 나아. 성능 차이는 실제 병목을 측정한 뒤 판단해.

콜론 유무가 빈 값의 의미를 바꿔

${var:-default}는 설정되지 않은 상태와 빈 문자열을 모두 기본값으로 바꾸지만 ${var-default}는 설정되지 않은 상태만 바꿔. 빈 값이 ‘사용자가 일부러 비움’을 뜻하는 설정이라면 이 차이가 중요해. 기본값 문법을 고르기 전에 설정되지 않은 상태와 빈 값을 같은 상태로 볼지 정해.

값이 아니라 패턴을 지워

#, ##, %, %% 오른쪽은 고정 문자열이 아니라 글로브 패턴이야. 변수에서 온 패턴을 그대로 넣으면 예상보다 넓게 잘릴 수 있어. 파일 경로처럼 입력 범위가 넓은 데이터는 대표 경계 사례를 표로 만들어 확인하자.

Code

실전 한 줄 명령·bash
file=/path/to/document.tar.gz
echo "${file##*/}"      # 출력: document.tar.gz(파일명)
echo "${file%/*}"       # 출력: /path/to(디렉터리명)
echo "${file%.gz}"      # 출력: /path/to/document.tar
echo "${file%%.*}"      # 출력: /path/to/document
name=alice
echo "${name^^}"       # 출력: ALICE

External links

Exercise

path=/Users/me/notes/idea.md를 설정하고 ${path##*/}, ${path%/*}, ${path%.md}, ${path//\//-}, ${#path}를 각각 출력해. 파일명, 디렉터리와 접미사를 얻는 확장이 slash가 없는 값이나 끝 slash에서도 의도대로 동작하는지 추가로 시험해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.