Brace Expansion

Brace 확장은 여러 확장과 치환 중에서 제일 먼저 일어나는 작업입니다. 그러므로 brace 확장에 사용되는 start, end range 값으로 변수를 사용할 수 없습니다 (변수확장이 뒤에 일어나므로). string list 에서 변수를 사용할 경우는 "$AA" or ${AA} 와 같이 해야 오류가 발생하지 않습니다. brace 확장은 double quotes 한 스트링 내에서는 일어나지 않습니다.

Brace 확장은 sh 에서는 사용할 수 없습니다.

String lists

{string1,string2,...,stringN}

, 가 사용되지 않은 단일 항목은 확장되지 않으며 , 전,후에 공백을 사용할 수 없습니다. string 내에 공백이 포함될 경우 quote 합니다.

# ',' 가 사용되지 않은 단일 항목은 확장되지 않는다.
$ echo {hello}
{hello}

# ',' 전,후에 공백이 사용되면 확장이 되지 않는다.
$ echo X{apple, banana, orange, melon}Y
X{apple, banana, orange, melon}Y

# string 내에 공백이 포함될 경우 quote 한다.
$ echo X{apple,"ban ana",orange,melon}Y
XappleY Xban anaY XorangeY XmelonY

Preamble 과 postscript 의 사용.

$ echo X{apple,banana,orange,melon}         # 여기서 X 는 preamble
Xapple Xbanana Xorange Xmelon

$ echo {apple,banana,orange,melon}Y         # Y 는 postscript
appleY bananaY orangeY melonY

# preamble, postscript 이 없을 경우 단지 space 로 분리되어 표시됩니다.
$ echo {apple,banana,orange,melon}         
apple banana orange melon    

$ echo X{apple,banana,orange,melon}Y
XappleY XbananaY XorangeY XmelonY

# '/home/bash/test/' 가 preamble 에 해당
$ mkdir /home/bash/test/{foo,bar,baz,cat,dog}
$ ls /home/bash/test/
bar/  baz/  cat/  dog/  foo/

$ tar -czvf backup-`date +%m-%d-%Y-%H%M`.tar.gz \
     --exclude={./public_html/cache,./public_html/compiled,./public_html/images} \
     ./public_html

# 'http://docs.example.com/slides_part' 는 preamble '.html' 는 postscript 에 해당
$ curl --remote-name-all http://docs.example.com/slides_part{1,2,3,4}.html
$ ls
slides_part1.html slides_part2.html slides_part3.html slides_part4.html

globbing 과 함께 사용

$ mv *.{png,gif,jpg} ~/Pictures/
$ mv *.{avi,mp4,mkv} ~/Videos/

null 값의 활용

$ echo aa{,}11
aa11 aa11

$ echo aa{,,}11
aa11 aa11 aa11

$ echo b{,,,A}a
ba ba ba bAa

$ cp test.sh{,.bak}
$ ls
test.sh test.sh.bak

$ ls  shell/{,BB/}rc.d
shell/rc.d
...
shell/BB/rc.d
...

$ paste <( shuf -n5 -i 1-99 ){,}
57      79
59      68
75      90
53      72
85      98

$ paste <( shuf -n5 -i 1-99 ){,,} 
48      18      91
58      24      95
91      54      66
31      14      10
44      8       55

변수와 같이 사용한 예

$ AA=hello

# 변수확장이 뒤에 일어나므로 {a,b}$AA 는 a$AA b$AA 와 같게 됩니다.
$ echo {a,b}$AA
ahello bhello

# 그냥 $AA 로 사용하면 X$AAY 와 같아지므로 ${AA} 나 "$AA" 를 사용합니다.
$ echo X{apple,${AA},orange,melon}Y
XappleY XhelloY XorangeY XmelonY

Ranges

{< START >...< END > }
{< START >...< END >...< INCR >}

Brace 확장은 변수확장 보다 먼저 일어납니다. 그러므로 start, end 값을 변수로 사용할 수 없습니다.

$ a=1 b=10

$ echo {$a..$b}         # brace 확장이 되지 않는다.      
{1..10}

start, end 값으로 숫자와 알파벳을 사용할수 있습니다.

$ echo {5..12}
5 6 7 8 9 10 11 12

$ echo {c..k}
c d e f g h i j k

$ echo {5..k}          # 숫자와 알파벳을 섞어서 사용할수는 없습니다.
{5..k}

######## Increment ########

$ echo {1..10..2}
1 3 5 7 9
$ echo {10..1..2}
10 8 6 4 2

$ echo {a..z..3}
a d g j m p s v y

zero 패딩

$ echo {01..10}
01 02 03 04 05 06 07 08 09 10

$ echo {0001..5}
0001 0002 0003 0004 0005

# img001.png ~ img999.png 까지 생성
printf "%s\n" img{00{1..9},0{10..99},{100..999}}.png

# 01 ~ 10 까지 생성
$ for i in 0{1..9} 10; do echo $i; done

Preamble 또는 postscript 의 사용.

$ echo 1.{0..9}
1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9

$ echo __{A..E}__
__A__ __B__ __C__ __D__ __E__

$ echo {A..D}___{1..3}
A___1 A___2 A___3 B___1 B___2 B___3 C___1 C___2 C___3 D___1 D___2 D___3

# 'http://docs.example.com/slides_part' 는 preamble '.html' 는 postscript 에 해당
$ curl --remote-name-all http://docs.example.com/slides_part{1..4}.html
$ ls
slides_part1.html slides_part2.html slides_part3.html slides_part4.html

Combining and nesting

{ } 를 서로 붙이면 combining 이 일어납니다.

$ echo {A..Z}{0..9}
A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 C0 C1 C2 C3 C4 C5 C6
C7 C8 C9 D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 F0 F1 F2 F3
F4 F5 F6 F7 F8 F9 G0 G1 G2 G3 G4 G5 G6 G7 G8 G9 H0 H1 H2 H3 H4 H5 H6 H7 H8 H9 I0
I1 I2 I3 I4 I5 I6 I7 I8 I9 J0 J1 J2 J3 J4 J5 J6 J7 J8 J9 K0 K1 K2 K3 K4 K5 K6 K7
K8 K9 L0 L1 L2 L3 L4 L5 L6 L7 L8 L9 M0 M1 M2 M3 M4 M5 M6 M7 M8 M9 N0 N1 N2 N3 N4
N5 N6 N7 N8 N9 O0 O1 O2 O3 O4 O5 O6 O7 O8 O9 P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 Q0 Q1
Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 S0 S1 S2 S3 S4 S5 S6 S7 S8
S9 T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 U0 U1 U2 U3 U4 U5 U6 U7 U8 U9 V0 V1 V2 V3 V4 V5
V6 V7 V8 V9 W0 W1 W2 W3 W4 W5 W6 W7 W8 W9 X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 Y0 Y1 Y2
Y3 Y4 Y5 Y6 Y7 Y8 Y9 Z0 Z1 Z2 Z3 Z4 Z5 Z6 Z7 Z8 Z9

{ } 안에서 , 로 분리하여 nesting 을 할수 있습니다.

$ echo {{A..Z},{a..z}}
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z

Range 값으로 변수를 사용하려면?

eval 명령을 사용하면 range 값으로 변수를 사용할 수 있습니다.

$ a=1 b=5
$ eval echo {$a..$b}    # eval 명령을 이용하면 원하는 결과를 얻을수 있습니다.
1 2 3 4 5

$ eval echo img{$a..$b}.png
img1.png img2.png img3.png img4.png img5.png

Brace 확장을 피하려면?

{ or } 를 escape 하거나 quote 해주면 됩니다.

$ echo \{a..c}
{a..c}

$ echo {a..c\}
{a..c}