Computer >> 컴퓨터 >  >> 프로그래밍 >> Bash 프로그래밍

Bash 중괄호 확장(Brace Expansion) 완벽 가이드: 6가지 실전 예제로 배우기

Bash 셸 확장(Shell Expansion)이란?

셸은 입력을 분석하는 과정에서 셸 확장(Shell Expansion)이라는 작업을 수행합니다. Bash는 다양한 종류의 확장 기능을 제공하며, 이 글에서는 그중에서도 중요한 중괄호 확장(Brace Expansion)에 대해 자세히 살펴보겠습니다.

이 아티클은 지속적으로 연재되고 있는 Bash 튜토리얼 시리즈의 일부입니다.

중괄호 확장(Brace Expansion)의 기본 개념

중괄호 확장은 임의의 문자열을 생성하는 데 사용됩니다. 하나의 인자만으로 여러 개의 수정된 명령줄 인자를 만들어낼 수 있는 강력한 기능입니다. 중괄호 안에 지정된 문자열들을 바탕으로 가능한 모든 조합이 생성되며, 선택적으로 접두사(preamble)접미사(postscript)를 붙일 수 있습니다.

확장은 왼쪽에서 오른쪽 방향으로 진행되며, 접두사는 중괄호 내 각 문자열 앞에, 접미사는 결과 문자열 뒤에 각각 추가됩니다.

$ echo last{mce,boot,xorg}.log
lastmce.log lastboot.log lastxorg.log

# last는 접두사(preamble), .log는 접미사(postscript)

위의 echo 문은 세 개의 로그 파일을 일일이 지정하지 않아도 되게 해줍니다. 마지막 부팅 로그(last boot log), MCE 로그, Xorg 로그의 내용을 확인하고 싶다면 위와 같이 중괄호 확장을 활용하면 됩니다.

1. 백업 스크립트 예제

$ cat bkup.sh
set -x # 명령어 확장 과정 출력
da=`date +%F`
cp $da.log{,.bak}

$ ./bkup.sh
++ date +%F
+ da=2010-05-28
+ cp 2010-05-28.log 2010-05-28.log.bak

위 백업 스크립트는 현재 날짜가 포함된 로그 파일을 .bak 확장자를 붙여 복사합니다. 중괄호 안의 첫 번째 요소가 비어 있으므로, 첫 번째 결과에는 접두사만 남게 됩니다. 즉 $da.log2010-05-28.log2010-05-28.log.bak 두 개의 인자로 확장됩니다.

2. 복원(Restore) 스크립트 예제

$ cat restore.sh
set -x # 명령어 확장 과정 출력
da=`date +%F`
cp $da.log{.bak}

$ ./restore.sh
++ date +%F
+ da=2010-05-28
+ cp 2010-05-28.log.bak 2010-05-28.log

복원 스크립트에서는 첫 번째 요소가 .bak이고 두 번째 요소가 비어 있습니다. 백업 예제와 정반대로 동작하여, .bak 파일을 원본 로그 파일로 복사합니다.

추가로 학습하실 분들은 이전에 다룬 bash 셸 함수 관련 아티클도 참고해 보시기 바랍니다.

3. 접두사·접미사 없이 중괄호 확장 사용하기

접두사와 접미사가 없다면, 단순히 중괄호 안에 나열된 요소들 자체로 확장됩니다.

$ cat expand.sh
echo {oct,hex,dec,bin}

$ ./expand.sh
oct hex dec bin

선택적인 접두사와 접미사 문자열 없이 사용하면, 결과는 주어진 문자열들이 공백으로 구분된 목록 형태로 출력됩니다.

범위(Range)를 활용한 중괄호 확장

중괄호 확장은 시퀀스(sequence) 생성에도 활용할 수 있습니다. 시퀀스는 정수 또는 문자 범위로 구성할 수 있습니다.

4. 정수 및 문자 시퀀스 예제

$ cat sequence.sh
cat /var/log/messages.{1..3}
echo {a..f}{1..9}.txt

$ ./sequence.sh
May  9 01:18:29 x3 ntpd[2413]: time reset -0.132703 s
May  9 01:22:38 x3 ntpd[2413]: synchronized to LOCAL(0), stratum 10
May  9 01:23:44 x3 ntpd[2413]: synchronized to
May  9 01:47:48 x3 dhclient: DHCPREQUEST on eth0
May  9 01:47:48 x3 dhclient: DHCPACK from 23.42.38.201
..
..
a1.txt a2.txt a3.txt a4.txt b1.txt b2.txt b3.txt b4.txt c1.txt c2.txt c3.txt c4.txt

첫 번째 cat 명령은 messages.1, messages.2, messages.3으로 확장되어 해당 파일들의 내용을 출력합니다. 다음 echo 문에서는 문자 시퀀스와 정수 시퀀스를 조합하여 사용했습니다.

증분값(Increment)을 사용한 시퀀스 생성

ksh(korn shell)의 중괄호 확장에서는 증분값(increment value)을 지정하여 시퀀스를 생성할 수 있습니다.

문법:
<시작>..<끝>..<증분>

증분값은 숫자여야 하며, 음의 정수도 사용할 수 있습니다. 다만 부호는 시작값과 끝값의 순서에 따라 자동으로 판단됩니다.

5. 시퀀스에서 증분값 활용 예제

$ ksh
$ echo /var/log/messages.{1..7..2}
/var/log/messages.1 /var/log/messages.3 /var/log/messages.5 /var/log/messages.7
$

이 기능을 활용하면 예를 들어 이틀 간격의 로그 파일만 골라서 확인할 수 있습니다.

중괄호 확장의 함정(Pitfall): 변수 확장 불가

중괄호 확장은 Bash 변수를 확장하지 못한다는 점에 주의해야 합니다. 중괄호 확장은 셸 확장 과정 중 가장 먼저 수행되는 단계이기 때문에, 변수는 그 이후 단계에서야 확장됩니다.

6. 확장 시 변수 사용 예제

아래 두 for문의 실행 결과를 비교하면 위에서 언급한 함정을 직접 확인할 수 있습니다.

$ cat var_seq.sh
# 시퀀스를 이용해 1부터 4까지 출력
for i in {1..4}
do
        echo $i
done
start=1
end=4

# 변수를 이용해 1부터 4까지 출력
echo "변수로 표현된 시퀀스"
for i in {$start..$end}
do
        echo $i
done

$ ./var_seq.sh
1
2
3
4
변수로 표현된 시퀀스
{1..4}

직접 값을 지정한 {1..4}는 정상적으로 1~4까지 출력되지만, 변수를 사용한 {$start..$end}는 확장되지 않고 그대로 {1..4}라는 문자열이 출력됩니다. 따라서 변수를 활용한 범위 시퀀스가 필요하다면 seq 명령어 등 다른 방법을 사용하는 것이 좋습니다.