Brace Expansion

this is one of those things where once you learn it you start seeing uses for it everywhere.

the idea

bash expands {} before doing anything else. so:

echo {one,two,three}
# one two three

doesn’t look impressive until you realize it works with any command.

stuff I do with it constantly

make a project structure in one shot:

mkdir -p project/{src,bin,docs,tests}

quick backup of a file (this one is chef’s kiss):

cp config.yml{,.backup}
# expands to: cp config.yml config.yml.backup

the empty string before the comma is doing the heavy lifting there. took me a sec to get that the first time.

rename extension:

mv report.{txt,md}

nuke multiple file types:

rm *.{log,tmp,bak}

sequences

echo {1..10}        # 1 2 3 4 5 6 7 8 9 10
echo {a..z}          # the whole alphabet
echo {01..20}        # zero-padded: 01 02 03 ... 20
echo {0..100..5}     # steps of 5 (bash 4+ only)

great for batch creating files:

touch log-{001..030}.txt

nesting (gets wild)

echo {web,api}-{dev,staging,prod}
# web-dev web-staging web-prod api-dev api-staging api-prod

combinatorial explosion in a good way.

one thing to know

braces expand whether or not files exist. globs (*) only match real files. so {a,b,c} always gives you three items. *.txt gives you nothing if there’s no .txt files. different tools for different jobs.


see also: bash-variable-tricks, bash-quick-loops, bash-history-expansion

gnu docs on brace expansion