변환 처리_09 언더스코어 등을 포함한 문자열에서 변수를 명확하게 구분하기

 
  • 출처 : 유닉스 리눅스 쉘스크립트 예제사전_한빛미디어

명령어: wc
키워드: 변수명, 문자열, 구분
사용처: 변수명 뒤에 이어진 문자열과 변수명을 명확하게 구분하고 싶을 때


실행예제

$ ./varname.sh
342 20150125_log

스크립트

#!/bin/sh

today="20150125"

# 셸 변수 today가 확장됨
wc -l ${today}_log

   

해설

이 스크립트는 20150125_log 라는 로그 파일의 줄 수를 표시합니다. wc 명령어는 파일 문자열과 줄 수를 조사하는 명령어로 -l 옵션을 쓰면 파일 줄 수를 표시합니다. 여기서 파일명이 “셸 변수명 + 언더스코어 + log”라는 셸 변수명 뒤에 언더스코어가 올 때 주의점을 살펴봅시다.

셸 스크립트 변수명으로 사용 가능한 문자는 알파벳, 숫자, 언더스코어 세 종류입니다. 어떤 셸 변수를 사용하는데 그 변수 뒤에 문자열을 연결하고 싶다고 합시다. 이때 뒤에 이어지는 문자가 셸 스크립트 변수명으로 사용하는 문자면 셸은 가능한 길게 변수명을 인식하므로 뒤에 있는 문자까지 변수명으로 보게 됩니다.

예를 들어 cat 명령어 실행 시 셸 변수가 today가 “20150125”로 확장될 거라고 보고 20150125_log 라는 파일을 표시하려고 다음과 같이 작성했다고 가정합니다.

today=20150125
cat "$today_log"

하지만 이 패턴에서 셸은 today_log를 셸 변수로 해석합니다. 그런 변수는 정의되어 있지 않으므로 cat ““이라는 빈 문자열에 대해 cat 명령어를 실행하게 되는데 그렇게 되면 파일이 존재하지 않아 에러가 출력됩니다(No such file or directory).

이런 경우에 셸 변수 뒤에 문자열을 연결하고 싶다면 변수명 구분이 명확해지도록 {}를 사용합니다. 즉, ${today}_log 라고 작성하면 today가 셸 변수라고 확실히 지정할 수 있어 뒤에 셸 변수에 쓰는 문자가 와도 제대로 해석할 수 있습니다.

중괄호가 필요 없는 경우라도 셸 변수를 중괄호로 감싸면 보기 좋아집니다. 문법상 필수는 아니지만 중괄호 사용을 생활화하기를 추천드립니다.

   

bash 배열 변수

bash 한정으로 배열 변수를 다룰 때는 반드시 변수명에 {}를 붙여야 합니다.

다음 실행 예에서 배열 변수 number에 {}를 붙이면 제대로 “one”이라는 값이 추출됩니다.

한편, {}를 붙이지 않으면 “$number에 문자열 “[1]”를 연결”이라는 의미가 되어 버립니다. 이때 배열 변수는 인덱스 없이 참조하면 배열 첫 요소가 참조되므로 “zero”에 “[1]”를 연결해서 zero[1]이라는 문자열을 보게 됩니다.

  • 배열 변수를 {}로 감싸기

    $ declare -a number=("zero", "one", "two")
    $ echo ${number[1]}
    one  #--------------- 기대한 대로 배열 취득
    
    $ echo $number[1]
    zero[1]  #----------- [1]이 문자열로 표시됨