Expansion in Bash

Expansion is a useful technique in Bash scripting. This technique is unique and differs from regular programming languages. This allows users to create a huge number of tokens just by writing a few letters. In this article, I will discuss different types of Bash expansion and their implementation while scripting. Hope you will get a clear idea after reading this.

Key Takeaways

  • Learning about Bash Expansion.
  • Different types of Expansion.
  • Basic syntax and implementation of particular Bash expansions.

Free Downloads

What is Bash Expansion?

Expansion in Bash scripting is a handy tool for automating repetitive tasks. Expansion creates multiple tokens based on the original parameter. When you use expansion, the command unfolds across each of the separated tokens. Hence, instead of using the original parameter’s expansion, Bash uses the value created by expanding the rest of the parameter as the new parameter. To have a deeper understanding, go through the various types of expansion discussed later.

Different Types of Expansion in Bash

Bash has different expansions like parameter expansion, brace expansion, arithmetic expansion, tilde expansion etc. Some of these are incredibly useful while others might not be used as often but still good to know. The syntax and implementation of each of the expansion is different. In the next part, I’ll break down a few of these Bash expansions and show you how to use them.

Parameter Expansion in Bash

Parameters are used to store data in Bash script. There are different types of parameters as well such as positional parameter, special parameter and variables. Dollar sign ($) is used for expanding parameters. The basic form of this type of expansion- ${PARAMETER_ NAME}, though curly braces are not mandatory in some cases.

1. Expanding Positional Parameter

Consider a script of adding two numbers given by the user. Within the script, numbers are taken as arguments. To access this one must use the technique of expanding positional parameters. For instance, $1, $2 will expand the first and second argument respectively.

Steps to Follow >

❶ At first, launch an Ubuntu Terminal.

❷ Write the following command to open a addition.sh file in the built-in nano editor:

nano addition.sh
EXPLANATION
  • nano: Opens a file in the Nano text editor.
  • sh: Name of the file.
Creating a Bash script in nanoScript (addition.sh) >
#!/bin/bash

# Assign the positional parameters to variables
echo "This script will add two numbers provided as arguments"
# Access the positional parameters given by the user
num1=$1
num2=$2

# Perform addition
result=$((num1 + num2))

# Display the result
echo "The sum of $num1 and $num2 is: $result"
EXPLANATION

#!/bin/bash” is called “shebang” that specifies the Bash interpreter. Then, it expands the first and second positional parameters using $1 and $2 and assigns to the variables num1 and  num2 respectively.

Next, it calculates the sum of num1 and num2 using arithmetic expression syntax and stores it in the result variable. Finally, it displays the result to the user.

❹ Use the following command to make the file executable:

chmod u+x addition.sh
EXPLANATION
  • chmod: Changes permissions.
  • u+x: Giving the owner executing permission.
  • sh: Name of the script.
Changing execution permission of a Bash scriptRun the script by the following command:
./addition.sh

Bash positional parameter expansionAs it shows the script takes two positional arguments such as 10 and 20. Then it calculates the sum of the given arguments.

NOTE: Expanding the first positional argument $0 gives the script name itself.

2. Expanding Variable and Its Properties

There are a couple of shell parameters that store information about variables. Let’s visualize those one by one. First of all, ${variable} will expand the value of the variable.

name="Anita"

echo ${name} #Expands the variable

Variable expansion in BashTo count the length of a variable expand the variable with “#” prefix.

my_string="Hello, World!"
echo ${#my_string}     #Count the length of the variable.

String length using bash parameter expansionIf a variable is not set then you can set the variable using the syntax ${var_name:=value}.

echo $name
echo ${name:=Anita}

Assigning new variable using parameter expansionLook at the list below. It contains other variable related parameter expansion available in Bash.

Parameter Expansion Description Example
${variable:-value} If the variable is unset or undefined, expand to the specified value. myvar=””
echo ${myvar:-“Default”}
# Output: Default
${variable:+value} If the variable is set or defined, expand to the specified value. myvar=”Hello”
echo ${myvar:+”World”}
# Output: World
${variable:start:length} Extract a substring from the variable starting at the given position with the specified length. text=”Hello, World!”
echo ${text:7:5}
# Output: World
${variable:start} Extract a substring from the variable starting at the given position to the end. text=”Hello, World!”
echo ${text:7}
# Output: World!
${variable/pattern/string} Replace the first occurrence of the pattern in the variable with the specified string. sentence=”I love apples.” echo ${sentence/apples/oranges}
# Output: I love oranges.
${variable//pattern/string} Replace all occurrences of the pattern in the variable with the specified string sentence=”I love apples and apples are great.”
echo ${sentence//apples/oranges} # Output: I love oranges and oranges are great.
${variable/#pattern/string} If the pattern exists at the beginning of the variable, replace it with the specified string. text=”apple pie”
echo ${text/#apple/cherry}
# Output: cherry pie
${variable/%pattern/string} If the pattern exists at the end of the variable, replace it with the specified string. text=”apple pie”
echo ${text/%pie/cake}
# Output: apple cake
${variable#pattern} Remove the shortest match from the beginning of the variable where the pattern matches. path=”/path/to/file.txt”
echo ${path#*/}
# Output: path/to/file.txt
${variable##pattern} Remove the longest match from the beginning of the variable where the pattern matches. path=”/path/to/file.txt”
echo ${path##*/}
# Output: file.txt
${variable%pattern} Remove the shortest match from the end of the variable where the pattern matches. path=”/path/to/file.txt”
echo ${path%/*} # Output: /path/to
NOTE: Single quote (‘’) ignores all special characters while double quote (“”) ignores special characters except “$”, “\” and backtick (`)

3. Command Substitution

Command substitution is another parameter expansion that begins with a dollar sign ($). However, following the dollar sign first bracket is used to expand the command. “$(Command_Name)” is the basic syntax for substituting commands.

For instance, substitute the date command and save the output in a variable.

today=$(date)
echo $today

Command substitution in BashHere, the date command is substituted and output is saved in the today variable.

NOTE: You can use the backtick (`) instead of dollar to substitute a Bash command.

Brace Expansion in Bash

Brace expansion is a powerful feature in Bash scripting. Curly braces “{}” are used for shell brace expansion. A basic example of shell brace expansion for a list can be as follows:

echo {Monday,Tuesday,Wednesday,Thursday,Friday}

Simple brace expansion in BashHere, curly brace expands each element of the list separated by a comma. The output of the echo command verifies the expansion.

You can also define a range to generate a sequence using brace expansion. The start and end of the range is separated by two dots (..)

echo {1..5}

Brace expansion in a rangeMoreover, you can utilize brace expansion to generate a sequence within a range with positive or negative increment. For instance, to generate a sequence of numbers from 1 to 15 with positive increment two type the following command in the Terminal.

echo {1..15..2}

Brace expansion with increment in BashFinally, brace expansion has nested use as well. This can be so powerful if perfectly used. An example of nested brace expansion looks like this.

echo {{A,B}{1,2}}

Nested brace expansion in BashSyntax of multiple nested brace expansion looks like this:

echo {{A,B}{1,2},{X,Y}{3,4}}

Multiple nested brace expansionHere, {A,B}{1,2} and {X,Y}{3,4} are two different nested brace structures.

Arithmetic Expansion

Arithmetic expansion is a useful feature in Bash that allows users to perform arithmetic calculations within a script. To enable arithmetic expansion simply enclose the expression to be evaluated within double parentheses. See the example of simple addition of 2 and 3.

echo $((2+3))

Bash arithmetic expansionLet’s evaluate a more complex expression and update variable values with the result.

result=0
result=$(( (5 + 3) * (10 - 2) / 4 ))

echo $result

Complex arithmetic operation using arithmetic expansionArithmetic expansion can also handle bitwise operations. The syntax for bitwise operation is “&”. On the other hand, syntax for regular multiplication is “*

x=5
y=3

echo $((x & y))

Bitwise and using arithmetic expansionBash Tilde Expansion

HOME is an environment variable that typically stores the path of a directory. This is called the home directory. Tilde(~) basically expands to the home directory or whatever is defined in the HOME variable. If the HOME variable is not set then it expands to the home directory of the current user.

Let’s run the command to see what’s stored in the HOME variable.

echo $HOME

HOME variable in BashIt shows /home/laku the current value of the HOME variable. Now, see how tilde(~) expands the path set in the HOME variable.

cd ~/Desktop/
EXPLANATION

The command cd is used to change the current working directory.The “~/Desktop/” portion represents an absolute path, indicating a directory named “Desktop” within the HOME directory. The program expands the HOME directory by the tilde sign (~) referenced before the Desktop directory.

Tilde expansion in BashAs you can see, the program immediately takes the user to the specified directory within the HOME directory by expanding the value of the HOME variable using tilde sign (~).

At this point, Let’s have a deeper look. What will happen if I change the value of the HOME variable! For instance, I want to set “/usr/local” as the new value of the HOME variable.

export HOME=/usr/local

Changing value of HOME variableOnce you run this command, this changes the HOME variable. You can see the effect instantly in the terminal as the previous tilde sign is gone and the full path of the current directory becomes visible. The “/home/laku” directory may be the user’s home directory however, this is not the path referenced by the tilde sign (~) as the value of the environment HOME variable is changed to “/usr/local”.

cd ~

Now run the above command to expand the new HOME variable using the tilde sign (~).Expanding new value of tildeCurrent directory changes after executing the command. To see my current directory I run the  pwd command. It shows “/usr/local” as the current working directory. It is expected as tilde (~) takes me to “/usr/local” because currently it is set in the HOME variable.

Bash History Expansion

Expertise in accessing the history makes life easier for command line users. You can recall previously executed commands and arguments instead of writing them again. I am going to show you a few tricks related to history expansion.

First of all, to access and re-execute the last command use double exclamation (!!).

!!
# Output: Return and execute the last command

Accessing last executed command using history expansionTo repeat the n-th number of commands from the history list use “!n”. For example, to get the first command from the history list run “!1

!1
# Output: Return and execute 1st command from the history list

Specific line from historyNow, if you want to get back the most recent command that starts with a specific string, then write that string after the exclamation.

!da
# Output: Return and execute last command that starts with da

Most recent command started with string daFor getting back the n-th argument of the last command use the “!!:n” syntax.

echo one two three
echo !!:2
# Output: echo two

Changing argument of last command using histroy expansionTo replace a certain string in the last executed command use “^old^new^” syntax. See the example to have a clear idea.

echo This is an example.
^example^sample^

Changing argument of last command using history expansionHere, the string “example” is replaced with “sample” in the last executed echo command.

Wildcard Expansion and Globbing in Bash

Wildcard expansion in some cases known as globbing is a feature that allows users to use some special characters or set of characters to match patterns. These special characters are known as wildcard characters. Examples of such characters are “*”,”?”,”!” etc. These characters are super helpful in finding or matching filenames or directories. The process of finding files or directories using wildcards is called globbing.

Let’s explore how to utilize wildcard characters. First of all, asterisk(*) matches a single or more characters. To give an example, consider a directory filled with files of a website. From the huge volume of files, let’s say I want to extract files with .md extension. The following command will do the task in seconds.

find -type f -name "*.md"

Wildcard expansion in BashHere, the wildcard(*) matches any character before “.md” and finds the files shown in the image.

Apart from asterisk(*), there are many other wildcards available in Bash. The below list contains useful wildcards and their function in Bash scripting.

Wildcard Syntax Function Example Explanation
* Match one or more characters *.txt Match with anything that ends with “.txt
? To match a single character image?.jpg Can match with “image1.jpg“, “imageA.jpg“, but not with “image12.jpg
! Match any single character not in the specified range [!0-9] Match any single character that is not a digit
^ Matches single character that is not specified within square brackets. [^123] Match with any single character other than “1”, “2”, or “3”
| Match with characters of one of the sides of the pipe (|) sign file(a|b).txt Match “filea.txt” or “fileb.txt
[:alpha:] Match any uppercase or lowercase letter file[:alpha:].txt Match with “filea.txt” or “fileZ.txt” but not “file1.txt
[:digit:] Match any digit within 0 to 9 file[:digit:].txt Match with “file1.txt” or “file0.txt” but not “filea.txt
[:alnum:] Match any letter from A to Z case-insensitively along with digits file[:alnum:].txt

 

Match with “file1.txt” or “file0.txt” but not “filea.txt
[:upper:] Match the uppercase letter only from A to Z file[:upper:].txt Match with “fileA.txt” or “fileB.txt” but not “filea.txt
[:lower:] Match with the lowercase letter only from a to z file[:lower:].txt Match with “filea.txt” or “fileb.txt” but not “fileZ.txt
[letters] Match any letter within the square bracket [aeiou] Match any single character that is vowels a, e, i, o, or u.
[:space:] Match with white space
[:blank:] Match with space or tab

nullglob is an option in Bash shell that defines whether the shell will change the globbing pattern as an empty string or leave it as it is. When enabled the pattern that doesn’t match with any filename turns to be a null string. Otherwise, the shell leaves the pattern unchanged as written in the command. To enable and disable the option follow the code below:

shopt -s nullglob
# enable

shopt -u nullglob
# disable

Array Expansion in Bash

Array expansion is quite useful to access and manipulate array elements within a Bash script. Expanding an array offers us accessing a particular element or looping through all the elements using a loop structure. “[@]” syntax is used to expand an array.

Let’s declare and define an array called arr1.

declare -a arr1

arr1=("element1" "element2" "element3")
echo "${arr1[@]}"
EXPLANATION
declare -a arr1” declares an array named arr1 using the declare command. Here -a defines that arr1 is an array.
Next, the declared arr1 is initialized using “arr1=(“element1”  “element2”  “element3”)” this code. This actually makes arr1 an array with three elements.
Finally, ${arr1[@]} expands the entire arr1 and prints each element as a separate string using echo command.
Array expansion in BashIn the output image, you can see that the echo command returns all the elements of arr1 by expanding the array using “[@]” syntax right after the name of the array.
declare -a arr1

arr2=("Ubuntu" "Redhat" "Kali Linux")
echo "${arr2[*]}"
EXPLANATION
declare -a arr2” declares an array named arr2 using the declare command. Here -a defines that arr2 is an array.
Next, the declared arr2 is initialized using “arr2=(“Ubuntu” “Redhat” “Kali Linux”)” this code. This actually makes arr2 an array with three different elements.
Finally, ${arr2[*]} expands the entire arr2 and prints each element as a single string using echo command.
Expands whole array as a stringOnce you execute the codes in the command line, you can see an output similar to the picture above. ${arr2[*]} expands the whole arr2 as a single string. Then the echo command prints out the result.
Looping through an array is the main purpose of expanding an array. Let’s see how to incorporate a loop structure while expanding an array.
You can follow this steps to learn about creating and saving shell scripts.

Script (arrayexpand.sh) >

#!/bin/bash

arr3=(15 10 5)

for item in "${arr3[@]}"; do
echo "$item"
done
EXPLANATION
The Bash script begins by declaring an array called arr3 with three integer elements: 15, 10, and 5. It then enters a for loop that iterates through each element in the arr3 using the “${arr3[@]}” syntax to expand the entire array. During each iteration, the current element is stored in the item variable, and the echo command is used to print the value of item to the terminal.
Looping through array using array expansionThe output shows that the loop iterates over the array and prints its elements 15,10 and 5 consecutively.

Conclusion

In conclusion, there are different types of Bash expansion. Each of them is quite useful while scripting. I believe after reading this article, you have an overall idea about Bash expansion. Follow our articles to learn more about each type of expansion.

People Also Ask

What is the first expansion in Bash?
There are a total of seven types of expansions in Bash. Among them brace expansion stood first in the order of the expansions.
Can I expand a variable inside a the single quote?
NO, you can’t. Inside the single quote, everything is represented as literal. So even if you use proper syntax of variable expansion, it will not expand the variable. It will rather return the string as written.
What is indirect expansion in Bash?
If a parameter starts with an exclamation (!), then Bash takes the rest of the parameter as the parameter name. Then expands the parameter as usual. This is called indirect expansion.
Rate this post
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

Leave a Comment