Bash Brace Expansion.

Most people who have had someone look over their shoulder while typing at a prompt have been hit with the question, “How did you do that?” Followed by a quick example of whatever nifty command they just executed. Of all the little bash tricks I know the one that I have explained to more people than any other is brace expansion. It’s a must have in the trick box of any bash user. Consider the following:
firewire@cartman:~> cp /etc/my.cnf /etc/my.cnf.bak
firewire@cartman:~> vim my.cnf
*edit edit edit*

Sometimes, before I knew about brace expanstion I would type my.cfn.bak then get slowed down by having to look for the right file. Other times when copying the bak file over the original I would mis-type my.cnf.

Introducing brace expansion. Brace expansion allows you to create multiple modified command line arguments out of a single argument.
firewire@cartman:~> echo foo{bar,baz}
foobar foobaz

How does this help our backup copy? Not all arguments int he brace set have to contain a string.
firewire@cartman:~> echo my.cnf{,.bak}
my.cnf my.cnf.bak

Replace echo with cp and you have just made a fool proof backup file. To restore just flip the arguments.
firewire@cartman:~> echo my.cnf{.bak,}
my.cnf.bak my.cnf

Brace expansion is a minor gain in this situation. Where it really prevails is with long path names such as
firewire@cartman:~> echo /usr/local/apache/conf/httpd.conf{,.bak}
/usr/local/apache/conf/httpd.conf /usr/local/apache/conf/httpd.conf.bak

[ Update 2006-2-1: Bash 3.0 introduces sequences in braces:

echo {1..3}{foo,bar}
1foo 1bar 2foo 2bar 3foo 3bar

]

5 Comments

  1. John says:

    Oh, how it hurts to find out how easy it could all have been.

    Having learned most of my scripting with ksh (on AIX), I really haven’t done enough to learn all the little treats in Bash. As it is, I only just recently learned to:

    for (( n = 1; n < 5; n++)); do echo $n; done

    But, oh my, look at my new play toy:

    for s in {X..Z}{1..4}{a..c}; do echo $s; done

    Thank you oh so much!

  2. vyom2k4 says:

    Wow! I didnt know braces could be used in sequence
    Thanks.

  3. Genstoo says:

    $echo foo{bar,baz}
    foobar foobaz

    $echo foo{,bar,baz}
    foo foobar foobaz

  4. Anonymous Penguin says:

    Hi Eric, as Genstoo mentioned, you should fix the example. It can be confusing to newbies.

  5. Eric Bergen says:

    Done and done.

Leave a Reply