Skip to main content
Bash

Using Brace Expansion in Bash Shell

Brace expansion in the bash shell is a lesser known but an awesome feature. Learn about using them like a Pro Linux user with practical examples.

Abhishek Prakash

Brace expansion {..} is one of the most underutilized but awesome shell features in Linux.

You can use it to print sequences of numbers and letters. Add two integers or letters separated by two dots in curly braces and see the magic.

In its simplest form, take this for example:

echo {1..10}

Can you guess the output?

1 2 3 4 5 6 7 8 9 10

The output sequence is printed in the same line with a space between them.

Let me give you some more examples of brace expansion so that you understand its functioning better.

Brace expansion examples

Let's say you want to get a reverse sequence of numbers from 7 to 1.

abhishek@LHB:~$ echo {7..1}
7 6 5 4 3 2 1

You can add leading zeroes:

abhishek@LHB:~$ echo {01..10}
01 02 03 04 05 06 07 08 09 10

You can use the brace expansion in the form of {x..y..z} to generate values from x till y while incrementing by z.

Let's say you want a sequence of even numbers till the number 15.

abhishek@LHB:~$ echo {0..15..2}
0 2 4 6 8 10 12 14

Or get an odd number sequence:

abhishek@LHB:~$ echo {1..15..2}
1 3 5 7 9 11 13 15

You can go in any incremental steps:

abhishek@LHB:~$ echo {100..1000..99}
100 199 298 397 496 595 694 793 892 991

It can also take negative numbers:

abhishek@LHB:~$ echo {3..-4}
3 2 1 0 -1 -2 -3 -4
⚠️
There must not be a space between the dots in the braces. Otherwise, the expansion won't work.

Using sequence of letters

So far I have only used sequences of numbers. But you can use it to generate sequences of letters as well.

abhishek@LHB:~$ echo {A..H}
A B C D E F G H

You can go reverse as well:

abhishek@LHB:~$ echo {H..A}
H G F E D C B A

Or go into incremental or decremental steps:

abhishek@LHB:~$ echo {H..A..2}
H F D B

You can also use small case letters the same way:

abhishek@LHB:~$ echo {a..f}
a b c d e f

Practical usage of brace expansion

So far, I have just shown examples of creating sequences with brace expansion in the bash shell.

But they are not practical examples. You can put it to some actual good use. Let me share a few such examples.

Create multiple files with similar names

Create files with a particular name pattern:

abhishek@LHB:~/test$ touch file_{1..10}.txt
abhishek@LHB:~/test$ ls
file_10.txt  file_2.txt  file_4.txt  file_6.txt  file_8.txt
file_1.txt   file_3.txt  file_5.txt  file_7.txt  file_9.txt

Create backup file

When you are about to edit a config file, it is recommended to make a backup. The general convention is to add a .bak extension to the original filename. This signifies that it's a backup of the given filename.

cp -p long_filename.txt long_filename.txt.bak

That's cool but let's use the brace expansion:

cp -p long_filename.txt{,.bak}

Yupe! This {,text} is not the usual {X..Y} pattern but it's a useful one you should know.

Example of brace expansion in bash shell

The -p option of the cp command preserves the file properties like ownership, timestamps, etc.

Use multiple braces

You can use multiple braces to create files with similar names and different extensions. That's only one example of using multiple braces.

abhishek@LHB:~/test$ touch {a,b,c}.{hpp,cpp}
abhishek@LHB:~/test$ ls
a.cpp  a.hpp  b.cpp  b.hpp  c.cpp  c.hpp
abhishek@LHB:~/test$

Using brace expansion in path

Let's say you have a similar directory structure with only a slight change. Brace expansion can be helpful here.

mv project/{new,old}/dir/file

The above command is equivalent to:

mv project/new/dir/file project/old/dir/file

Not everything can be expanded

That goes without saying. You are looking to create sequences so it should be something that could be created into sequences. If you use a weird combination, it won't be expanded.

abhishek@LHB:~$ echo {1..Z}
{1..Z}

You cannot use decimal points.

abhishek@LHB:~$ echo {1..5..0.5}
{1..5..0.5}

It may generate weird results for some weird combinations:

abhishek@LHB:~$ echo {a..F}
a ` _ ^ ]  [ Z Y X W V U T S R Q P O N M L K J I H G F

Conclusion

When you are new to it, brace expansion will feel cumbersome. I mean, how long does it take to type them all by hand?

But once it gets into your muscle memory, it takes your Linux command skills to another level.

So, try and use brace expansion in your shell scripting as much as possible.

Abhishek Prakash