How to Use Brace Expansion in Bash Scripting [3 Cases]

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, search path names, or in many other useful contexts. In this article, you’ll get a complete idea about brace expansion and its usage.

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 Create Directories in Bash

Brace expansion of a simple list without any pattern requires explicitly indicating all the items with the curly brace. To create multiple directories using brace expansion, follow the steps:

  1. At first, launch an Ubuntu Terminal.
  2. Open a file named bexpansion.sh using:
    nano bexpansion.sh

    Creating a Bash script in nano

  3. Copy the following scripts and paste them into the file.
    #!/bin/bash
    mkdir {Ubuntu,Redhat,Fedora}
    EXPLANATION

    #!/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.

  4. Use the following two commands to make the file executable:
    chmod u+x bexpansion.sh

    Changing permission of a Bash script

  5. Run the script by the following command:
    ./bexpansion.sh

    Creating folders using brace expansion in BashAs you can see, the program created three different directories by expanding the list within curly braces.

Case 2: Brace Expansion to Create a 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}”. The below Bash script will make files for each day of a particular month using brace expansion of a range:

#!/bin/bash

mkdir January
cd January
touch {1..31}
ls
EXPLANATION

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.

Brace expansion of a range in BashAs 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

Brace expansion with incrementMoreover, you can generate a sequence with a negative increment as follows.

echo {15..1..-1}

Brace expansion with decrementFinally, brace expansion has its nested use. You can combine multiple brace expansions to generate complex strings. For example:

echo {a,b,c{1,2,3},d}

Nested brace expansion in BashHere, “{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.

The below table 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!

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}

Brace expansion with preambleThis script creates the preamble for globbing.

#!/bin/bash

mkdir /usr/local/bin{documents,code,backup,temp}
echo “Folders created successfully”
EXPLANATION

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.

Executing bash script to create folders using brace expansion with preambleOnce 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.Checking the created foldersIt 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."

Brace expansion with postscriptHere, postscript “.txt has been processed” has been added with each of the items of brace expansion.

Let’s see how this can be useful for creating multiple text file.

#!/bin/bash

rm {1..31}.txt
echo "Successfully deleted the files"
EXPLANATION

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.

Executing postscript.sh to create files using brace expansionOnce 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 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.

Brace expansion with preamble and postscriptHere 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.

People Also Ask

What is brace expansion for loop?

You can use brace expansion to create an iterable or sequence to iterate for the for loop. This makes the loop structure short and simple. To be specific for i in {1..5} makes the loop to iterate from 1 to 5.

Bash brace expansion not working?

There may be multiple reasons behind brace expansion not working. Errors may lie in the syntax of brace expansion and the range you provide to expand.

What is the difference between brace expansion and globbing?

The main difference is that brace expansion creates strings or sequences of strings while globbing matches patterns.

What are the alternatives of brace expansion for generating sequence?

To generate a sequence just like brace expansion, you can use the seq command. It is multi-functional and allows you to provide arguments.

Related Articles


<< Go Back to An Overview of Shell Expansion in Bash | Bash Scripting Tutorial 

5/5 - (12 votes)
LINUX
FUNDAMENTALS
A Complete Guide for Beginners Enroll Course Now
Md Zahidul Islam Laku

Hey, I'm Zahidul Islam Laku currently working as a Linux Content Developer Executive at SOFTEKO. I completed my graduation from Bangladesh University of Engineering and Technology (BUET). I write articles on a variety of tech topics including Linux. Learning and writing on Linux is nothing but fun as it gives me more power on my machine. What can be more efficient than interacting with the Operating System without Graphical User Interface! Read Full Bio

2 thoughts on “How to Use Brace Expansion in Bash Scripting [3 Cases]”

  1. okay, but how to escape this damn braces in shell scripts, if command needs it as it own variable only like in tar excluded={..}, hi

    Reply
    • I think you want to get rid of brace expansion especially while using the tar command with its --exclude=pattern option. Your pattern in this case is the literal {..} that itself contains the braces. To ensure Bash treats it as a literal and prevents brace expansion, enclose the literal by single or double quote like:

      tar --exclude='{..}'

      or,

      tar --exclude="{..}"

      If it doesn’t fix the issue, feel free to reach us with the details of your problem. Thank you for your patience.

      Reply

Leave a Comment