Brace expansion is one of the most useful features of BASH when it comes to managing files. But a lot of people don’t know about it, so here’s a quick little tutorial on what brace expansion is, and some practical examples of how you can use it.

Brace expansion can be used to create multiple text strings from a pattern contained within curly braces. They can be used alone but they are more useful when used as a substring within a larger string.

The pattern within the braces can be a series of strings separated by commas, or you can define a range of number or letters by using .. between the start and end. A series of numbers can also be zero-padded by padding the beginning of your range.

[~]$ echo {A,B,C}
A B C
[~]$ echo {1,2,3}
1 2 3
[~]$ echo {A..E}
A B C D E
[~]$ echo {1..15}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
[~]$ echo {01..15}
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
[~]$ echo {001..15}
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015
[~]$ echo {Z..J}
Z Y X W V U T S R Q P O N M L K J

You can surround the brace expansion with text to make some more useful output. The string preceding the brace expansion is called the preamble and the string following is called the postscript. You can use this to create many unique file names with one line.

[~]$ touch newTxtFile{01..06}.txt
[~]$ ll
total 0
-rw-r--r-- 1 d d 0 Aug  9 15:41 newTxtFile01.txt
-rw-r--r-- 1 d d 0 Aug  9 15:41 newTxtFile02.txt
-rw-r--r-- 1 d d 0 Aug  9 15:41 newTxtFile03.txt
-rw-r--r-- 1 d d 0 Aug  9 15:41 newTxtFile04.txt
-rw-r--r-- 1 d d 0 Aug  9 15:41 newTxtFile05.txt
-rw-r--r-- 1 d d 0 Aug  9 15:41 newTxtFile06.txt

Another common use of brace expansion would be to create a directory structure. For instance, say I wanted to create a directory for every month with 30 days. Then within each month directory, create a directory for each day. And within each day create a textfile called dailyNotes.md. This whole structure can be created with two commands and one line.

[~]$ mkdir -p April,June,September,November}/{01..30}/; touch {April,June,September,November}/{01..30}/dailyNotes.md
[~]$ tree April
April/
├── 01
│   └── dailyNotes.md
├── 02
│   └── dailyNotes.md
├── 03
│   └── dailyNotes.md
├── 04
│   └── dailyNotes.md
...

Brace expansions can also be nested. This gives you the ability to create even more complex file naming schemes or directory structures.

[~]$ echo pre-{nOne{1,2},nTwo{3,4}}-post
pre-nOne1-post pre-nOne2-post pre-nTwo3-post pre-nTwo4-post

Another situation where brace expansion comes in handy is when you want to do something to several different files with names that are difficult to glob together. Just stick them all in a brace expansion and you’re done. The downside is that tab-completion will not work as your are creating your brace expansion, so you will need to take care to type the file names correctly.

[~]$ rm -v {"some file with spaces.txt",anotherFileHere.md,your_mom.png}
removed 'some file with spaces.txt'
removed 'anotherFileHere.md'
removed 'your_mom.png'

That’s about all there is to know about brace expansion. A simple little command line tool that can save you lots of duplicated effort!