This article is part of our on-going Bash Tutorial series.
Brace expansion is used to generate arbitrary strings. Brace expansion allows you to create multiple modified command line arguments out of a single argument. The specified strings are used to generate all possible combination with the optional surrounding preambles and postscripts. The preamble is prefixed to each string contained within the braces, and the postscript is then appended to each resulting string, expanding left to right.
$ echo last{mce,boot,xorg}.log lastmce.log lastboot.log lastxorg.log where last is Preamble and .log is the postscript
The above echo statement avoids you to specifying the three log files separately. If you want to view the content of the last boot log, mce log and xorg log you can use the brace expansion as shown in the above echo statement.
$ cat bkup.sh set -x # expand the commands 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
In the above backup script, it copies the current date log file with the extension .bak. The first element is empty in the braces, so first element will have only preamble.
$ cat restore.sh set -x # expand the commands 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
In the restore script, the first element in the parameter is .bak where as second element is empty.
Also, refer to our earlier article on bash shell functions for additional reading.
If there is no preamble and postscript, it just expands the elements given in the braces.
$ cat expand.sh echo {oct,hex,dec,bin} $ ./expand.sh oct hex dec bin
Without the optional preamble and postscript strings, the result is just a space separated list of the given strings
Brace expansion expands the sequences also. The sequences can be of integers or characters.
$ 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
The first cat command, expands messages.1,messages.2 and messages.3 and displays the content. and in the next echo statement character and integer sequences are combined and used.
In kshell brace expansion, you can use increment value, to generate the sequences.
Syntax:.. ..
incr is numeric. You can use a negative integer, but the correct sign is deduced from the order of start and end.
$ ksh $ echo /var/log/messages.{1..7..2} /var/log/messages.1 /var/log/messages.3 /var/log/messages.5 /var/log/messages.7 $
Using this you could see the alternate days logfiles.
Brace expansion does not expand bash variables, because the brace expansion is the very first step of the shell expansion, variable will be expanded later.
If you see the output of the following two for statement, you could identify the above pitfall.
$ cat var_seq.sh # Print 1 to 4 using sequences. for i in {1..4} do echo $i done start=1 end=4 # Print 1 to 4 using through variables echo "Sequences expressed using variables" for i in {$start..$end} do echo $i done $ ./var_seq.sh 1 2 3 4 Sequences expressed using variables {1..4}