Brace expansion is a feature in Bash that permits to generate a range of strings of various types. These strings can be used to generate files or directories, in searching pathname or in many other useful contexts. In this article, I will provide you with a complete idea about brace expansion and its usage.
Key Takeaways
- Expanding a simple list.
- Learning about the expansion of a range.
- Understanding about prefixes and suffixes while expanding.
- Visualizing nested brace expansion.
3 Different Cases of Brace Expansion in Bash Scripting
The list or lists of brace expansion may differ based on the context of expansion. For instance, expanding a range doesn’t require including all the items within the range while expanding a simple list does. However, the basic syntax of brace expansion remains the same. The list that needs to be expanded must be put with curly “{}” braces.
Case 1: Brace Expansion of a List to Make Directories in Bash
Brace expansion of a simple list without any pattern requires explicitly indicating all the items with the curly brace. Look at the basic example of brace expansion.
{Ubuntu,Redhat,Fedora}
# Output: Ubuntu Redhat Fedora
Let’s have a look how this type of expansion can be helpful for creating multiple directories at a time.
❶ At first, launch an Ubuntu Terminal.
❷ Write the following command to open a file named bexpansion.sh in the build-in nano editor:
nano bexpansion.sh
- nano: Opens a file in the Nano text editor.
- bexpansion.sh: Name of the file.
Script (bexpansion.sh) >
#!/bin/bash
mkdir {Ubuntu,Redhat,Fedora}
“#!/bin/bash” specifies that the script should be interpreted and run using the Bash shell. It utilizes the mkdir command to create three directories named “Ubuntu” “Redhat” and “Fedora” in the current directory. The script employs brace expansion, to generate these directory names within curly braces, separated by commas.
❹ Use the following two commands to make the file executable:
chmod u+x bexpansion.sh
- chmod: Changes permissions.
- u+x: Giving the owner executing permission.
- bexpansion.sh: Name of the script.
./bexpansion.sh
As you can see, the program created three different directories by expanding the list within curly braces.
Case 2: Brace Expansion of a Range to Create Sequence of Files
Brace expansion is super useful when you use it for expanding a range. To expand a range the start and the end of the range should be specified within the curly braces separated by two dots. The syntax should be- “{start . . end}”. Let’s create a Bash script that will make files for each day of a particular month using brace expansion of a range.
Script (range.sh) >
#!/bin/bash
mkdir January
cd January
touch {1..31}
ls
This Bash script creates a directory named “January” using mkdir command. Then it changes the current directory to “January” using the cd command. Finally, it generates 31 empty files named “1” through “31” representing the days of the month. Finally, it lists the files using the ls command.
Run the range.sh script by the following command:
./range.sh
As you see, the program creates empty files for each day of the month “January” by expanding the range {1..31}.
Apart from expanding a range with start and end values only, you can generate strings or numbers with increments or decrements as well. For example, let’s create a sequence from 1 to 15 with an increment of 2.
echo {1..15..2]
# Output: 1 3 5 7 9 11 13 15
Moreover, you can generate a sequence with a negative increment as follows.
echo {15..1..-1}
Finally, brace expansion has its nested use. You can combine multiple brace expansions to generate complex strings.
Here, “{1,2,3}” is nested within the outer curly braces. While expanding, these nested curly braces also expand as you can see c1, c2 and c3 in the output.
Look at the table to have all the ideas at once. It contains possible brace expansion associated with range.
Brace Expansion | Example | Output |
---|---|---|
{start..end} | {1..3} | 1 2 3 |
{start..end..increment} | {2..10..2} | 2 4 6 8 10 |
{start..end..decrement} | {5..1..-1} | 5 4 3 2 1 |
{start..end}{start..end} | {a..c}{1..3} | a1 a2 a3 b1 b2 b3 c1 c2 c3 |
{start..end..increment}{start..end} | {1..3..1}{a..c} | 1a 2a 3a 1b 2b 3b 1c 2c 3c |
Not All Ranges Can Be Expanded!
Expanding ranges to generate sequences in Bash is quite efficient. However, there are a limited number of ranges that can be expanded in this way. The following tables will give you a rough idea about which ranges you can expand and which you can’t use brace expansion.
Valid Range | Example | Output |
---|---|---|
Numeric Sequences | {1..5} | 1 2 3 4 5 |
Alphabetical Sequences | {a..e} | a b c d e |
Combined Sequences | {a..e}{1..3} | a1 a2 a3 b1 b2 b3 c1 c2 c3 d1 d2 d3 e1 e2 e3 |
Leading Zeros | {01..05} | 01 02 03 04 05 |
The below list contains some probable ranges that may end up with errors. Because these ranges are not valid or brace expansion doesn’t work that way.
Invalid Range | Example |
---|---|
Non-Numeric Ranges | {01/01..12/31} -Date like ranges doesn’t work. |
Arithmetic Expressions | {1+1..5+5} won’t expand as an arithmetic sequence. |
Variable Values | x=3; {1..$x} will not expand as expected. |
Nested Ranges | {1..{3..5}} is an invalid nested range. |
Alphanumeric Sequences with Gaps | {a..f..2} won’t expand as “a c e“ |
Case 3: Brace Expansion With Preamble and Postscript in Bash
Sometimes brace expansions are used with preamble(prefix) and postscript(suffix). These help users to employ brace expansion efficiently and creatively to achieve certain tasks.
A. Expansion With Only Preamble
Preamble or prefix means certain text that is added before brace expansion. This structure is quite helpful when the common prefix is too long. A basic example of a preamble in brace expansion can be the following.
"I love scripting in "{Ubuntu, Fedora, Kali}
Let’s create a script to use preamble for globbing.
Script (preamble.sh) >
#!/bin/bash
mkdir /usr/local/bin{documents,code,backup,temp}
echo “Folders created successfully”
The provided Bash script creates four directories within the /usr/local/bin directory. It utilizes brace expansion, which allows the script to create multiple directories namely “documents”,“code”,“backup” and “temp” with a single mkdir command.
Run the preamble.sh script by the following command:
sudo ./preamble.sh
Once executed the program will create directories in the folder that is specified by the preamble “/usr/local/bin”.
You can check the contents of the preamble using ls command.It shows that directories are created successfully in the location specified by the preamble.
B. Expansion With Postscript in Bash
Like a preamble, postscript, or suffix to brace expansion enhances its functionality, especially when you want to include longer text after the expansion. Let’s begin by examining a straightforward example of brace expansion with a postscript.
echo {readme,bug,update}".txt has been processed."
Here, postscript “.txt has been processed” has been added with each of the items of brace expansion.
Let’s see how this can be useful while scripting.
Script (postscript.sh) >
#!/bin/bash
rm {1..31}.txt
echo "Successfully deleted the files"
The Bash script, “rm {1..31}.txt” utilizes brace expansion to generate a list of file names from “1.txt” to “31.txt” and then employs the rm command to delete these files, effectively removing all files with names ranging from “1.txt” to “31.txt” from the current directory.
Run the postscript.sh script by the following command:
./postscript.sh
Once executed the script deletes files ranging from “1.txt” to “31.txt” using “.txt” as a postscript after brace expansion.
C. Expansion With Preamble and Postscript
One can use preamble and postscript together to perform more complex and exceptional tasks. It can be file creation, globbing or any other task. Just see the basic example to have an idea of how it works.
echo "I know "{Anita,Mohammed,Kelly}" as an adroit programmer."
# Output:I know Anita as an adroit programmer. I know Mohammed as an adroit programmer. I know Kelly as an adroit programmer.
Here the text “I know ” and “ as an adroit programmer” are used as preamble and postscript respectively.
You can use preamble and postscript to create multiple files using brace expansion. Think about the following code.
touch file{1..31}.txt
This creates files ranging from “file1.txt” to “file31.txt” where the text “file” and “.txt” files are used as preamble and postscript respectively.
Conclusion
In conclusion, brace expansion is indeed a useful feature for generating strings efficiently and quickly. When you are familiar with the syntax and different ranges, it is easy to apply brace expansion in various contexts. I believe from now you can apply all the techniques related to brace expansion.