Parameter Expansion in Bash [3 Main Types]

Parameter expansion is one of the key concepts in Bash scripting. It is useful to find, replace or modify the value of a parameter. The multi-purpose dollar ($) symbol is used for parameter expansion. Typically, $parameter_name will expand a parameter with the particular name. This article discusses parameter expansion in depth.

Basics of Parameter Expansion in Bash

“${parameter_name}” is the basic syntax of parameter expansion in Bash. It allows users to access the value of the parameter. The optional curly braces “{ }” is often used to avoid ambiguity between the value of the parameter and the characters enclosed in it. Let’s see a practical example:

user=Jhon
echo ${user}

Setting up parameter valueIn the first line of the code, user is a variable, in other words, a parameter. The value of the parameter is set to Jhon. The following line expands the parameter using “${user}”.

Indirect Parameter Expansion in Bash

While expanding, an exclamation mark before the parameter name like- “${!parameter_name}” refers to a level of indirectness. This means Bash first expands the part after the exclamation sign. Then the value of the first expansion is used as a new parameter. It then expands the new parameter, rather than using the original parameter’s expansion. Look at the following example to have a clear idea:

user=Jhon
admin=user
echo {!admin}

Indirect parameter expansion in BashIn the above image, ${!admin} first expands the parameter admin and retrieves its value which is user. Then user is used as the new parameter. Finally, the value of the user parameter is expanded as you see Jhon is the output of the echo command.

NOTE: When the nameref is an array variable, the exclamation sign doesn’t refer to indirect expansion. So ${!name[@]} or ${!name[*]} is an exception of indirect expansion. Rather than regular parameter expansion, these expand to the list of indices of the assigned array or keys in case of an associate array. ${!prefix*} or ${!prefix@} also doesn’t refer traditional parameter expansion. These expand to the names of the variables that start with the particular prefix.

Default Value Expansion of a Bash Parameter

You can set the default value or initial value of a parameter using parameter expansion. The default value is the value of a variable or parameter when that variable is either unset or empty. See the following example to see how it works:

First, unset the parameter if it’s already set. For example, I unset the parameter user using the unset command as follows. Once unset, expansion of the user parameter shows nothing in the terminal.Unsetting a parameter in BashNow, use parameter expansion to set a default value for the user parameter. The syntax is ${parameter_name:=default value}. I set Anita as the default value for the user parameter.

echo ${user:=Anita}
echo $user

Setting default value of a parameterAt this point, if the value of the user parameter is set then default value expansion doesn’t expand the value mentioned as the default value. Though I set the value of user as Anita as the default value, it expands to Jhon as user is set to Jhon already.Checking default value and set valueThere are other syntaxes related to default value expansion. The important thing to understand about those syntaxes is “:-” check for a parameter that is unset or null. If colon is omitted then it checks for a parameter that is null. On the contrary, if colon is included then the operator checks the existence of a parameter and its value if not null. I have listed a few operations below that include colon.

Syntax Explanation
${parameter:-value} If the parameter is null or unset, it is replaced by value. If parameter has a value, it is not changed.
${parameter:?value} If parameter is null or unset, an error is triggered, and value is displayed. If parameter has a value, it is not changed.
${parameter:+value} If parameter is null or unset, nothing is substituted, and parameter remains empty. If parameter has a value, it is replaced by the new value.

3 Types of Parameter Expansion in Bash

Parameter expansion is a very useful technique. One can easily access a parameter and its basic information through the proper utilization of parameter expansion. Moreover, one can modify the values of parameters and perform many other operations at ease using parameter expansion. I am going to cover the main 3 types of those.

Type 01: Basic String Operations Using Bash Parameter Expansion

To perform basic operations, such as finding the length of a parameter, capitalizing or lowercasing the parameter requires proper use of special characters like # and ^ before or after the parameter name. Let’s first explore how to find the length of a parameter.

1. Length of a Parameter Using Parameter Expansion

To find the length of a parameter, place a # before the name of the parameter. For example, if the name of a parameter is user, ${#user} will expand to the length of its value. Here’s the bash script for this:

user=andrew
echo ${#user}

Length of parameter using parameter expansionHere the length of andrew is 6 and it is stored in the parameter user. So ${#user} returns six as you can see in the above image.

2. Capitalizing the Value of a Parameter Using Parameter Expansion

You can capitalize the value of a parameter using the caret ^ sign. A single caret should be placed at the end of the parameter name to capitalize the first letter. Recall the previous context of the parameter user.

user=andrew
echo ${user^}

Uppercasing the first character using parameter expansion in BashHere, ${user^} is used to capitalize the first letter of the user variable. Therefore, the value of the variable andrew results in Andrew.

To capitalize the whole value of the parameter, use a double caret sign instead of one.Uppercasing whole parameter using parameter expansion in BashIn the above image, ${user^^} capitalizes the whole value of the user parameter. Hence, the value of the parameter Andrew results in ANDREW.

3. Lowercasing the Value of a Parameter Using Parameter Expansion

To convert a parameter’s value to lowercase, use comma after the parameter’s name. A single comma changes the first character of the parameter’s value to lowercase, while a double comma changes the entire value to lowercase.Lowercasing parameter expansion using parameter expansion in BashIn the above image, ${user,} converts the first character of the user parameter to lowercase, making the value change from ANDREW to aNDREW.Lowercasing whole parameter using parameter expansion in BashThe above image shows that ${user,,} converts all the characters of the user parameter to lowercase and changes the value from ANDREW to andrew.

4. Parameter Expansion Operators

The are few operators available to quickly manipulate the value of a parameter. The syntax of using these operators is ${parameter@operator}. Let’s say I have a variable user=Jhon. Now I can use the operator U to convert all the lowercase letters of the value of user to uppercase. I can simply do this using ${user@U}. The below list can help you to find other useful operators:

Operators Explanation
U Converts lowercase alphabetic characters in the value of parameter to uppercase.
u Converts the first character of the value of parameter to uppercase, if it’s alphabetic.
L Converts uppercase alphabetic characters in the value of parameter to lowercase.
Q Quotes the value parameter in a format that can be reused as input.
E Expands backslash escape sequences in the value of parameter as with the $’…’ quoting mechanism.
P Expands the value of the parameter as if it were a prompt string.
A The expanded string generates a string in the form of an assignment statement or declare command. Evaluating it recreates parameter with its attributes and value.
K Produces a possibly-quoted version of the value of parameter. For arrays, it prints index or key-value pairs.
a Generates a string consisting of flag values representing parameter’s attributes.
k Similar to the “K” but expands keys and values of arrays to separate words after word splitting.

Type 02: Substring Slicing Using Parameter Expansion in Bash

It is perfectly fine to use commands like awk or sed to modify or extract substrings. However, you can also utilize the built-in syntax of parameter expansion to modify or extract parts from the value of a parameter. Colon is used to specify the index of a substring after the name of a parameter. Let’s explore this with practical examples:

# syntax: ${parameter_name:start}
str="I use Arch, Btw"
echo ${str:2}

Substring expansion using parameter expansion in BashIn this demo, ${str:2} extracts a substring from the value stored in the str variable. The substring starts at index 2, which corresponds to the u in the string “I use Arch, Btw” and it extends to the end of the string. As a result, you will see “use Arch, Btw”.

# syntax: {parameter:start:end}
str="I use Arch, Btw"
echo ${str:0:10}

Substring expansion using parameter expansion in Bash with start and end indexIn this demo, ${str:0:10} extracts a substring from the value stored in the str variable. The substring starts at index 0, which corresponds to the “I” in the string “I use Arch, Btw” and it extends up to index 10 which corresponds to the “h” in the string. The result is “I use Arch” as highlighted in the image.

NOTE: if either of the indices is not defined explicitly in parameter expansion, Bash takes the start index as zero and the end index as the end of the string.

Type 03: Substitution With Parameter Expansion in Bash

You can even perform find and replace operations using parameter expansion in Bash. Let’s see some practical examples.

1. Find and Replace Using Parameter Expansion: “${parameter/find/replace}”

The basic syntax for find and replace operation is ${parameter/find/replace}. Look at the example below to see how to find and replace using parameter expansion:

str= "Make each program do one thing well."
echo ${str/program/code}

Find and replace using Bash parameter expansion${str/program/code} replaces the first occurrence of program with code in the string stored in the variable str and then prints the modified string.

2. Find and Replace With Wildcards Using Parameter Expansion

It raises no error if you use wildcard characters such as asterisk or question mark to match pattern in parameter expansion. Look at the following code:

str= "Make each program do one thing well."
echo ${str/*program/}

Find and replace with wildcards using Bash parameter expansion${str/*program/} matches the word program and everything before by using the asterisk and replaces the match with nothing. Because nothing is specified after the second forwardslash. Hence it modifies the string “Make each program do one thing well.” and removes the part “Make each program”. The modified result “do one thing well” is displayed in the terminal.

3. Global Replacement in Parameter Expansion: “${parameter//find/replace}”

Now, I take a new string to demonstrate global replacement using parameter expansion. See the next two lines of command:

str="gnu stands for gnu's Not UNIX"
echo ${str//gnu/GNU}

Global replacement using Bash parameter expansion${str//gnu/GNU} replaces all instances of gnu with GNU in the string stored in the str variable and then prints the modified string. The output is “GNU stands for GNU’s Not UNIX.” as shown in the image.

NOTE: There is another syntax for global replacement using parameter expansion. ${parameter/string1/string2/g} replaces all occurrences of string1 with string2. The “g” tag indicates that the replacement should be global.

4. Using “#” to Remove Matching From the Begining of a Parameter

Now, I want to talk about the use of the # character for substring expansion. ${parameter/#pattern/} actually removes the shortest matching pattern from the beginning of the parameter. See the example below:

path="/path/to/myfile.txt"
echo ${path#*/}

Remove matching from the beginning of a parameterHere, ${path#*/} removes the shortest matching pattern from path which is only the first forward-slash (“/”). So, the modified value of the parameter is “path/to/myfile.txt”.

“##” is also used to modify the value of a parameter. ${parameter/##pattern/} removes the longest matching pattern from the beginning of the parameter.

path="/path/to/myfile.txt"
echo "${path##*/}"

Remove longest matching from the beginning of a parameterHere the longest matching pattern for the ${path##*/} code is up to the last forward slash of the value of path. So “/path/to/myfile.txt” results in “myfile.txt”.

5. Using “%” to Remove Matching From the End of a Parameter

Percentage “%” works just the opposite of “#”. For example, a single “%” will remove the shortest matching pattern from the end of a parameter. The syntax should be look like this- ${variable%pattern}.

path="/path/to/myfile.txt"
echo "${path%/*}"

Remove matching from the end of a parameterHere the shortest pattern that ${path%/*} matches for the path value “/path/to/myfile.txt” is everything after the last forward slash. Hence it removes the part “myfile.txt” and results in “/path/to”.

On the other hand, double percentage “%%” works just the opposite of “##”. It removes the longest matching pattern from the end of a parameter. The syntax should be- ${variable%%pattern}.

path="/path/to/myfile.txt"
echo "${path%%/*}"

Remove longest matching from the end of a parameterThe longest matching pattern that ${path%/*} matches for the path value /path/to/myfile.txt is everything after the first forward slash. Hence there is nothing left to display at it matches the whole value.

There are many other ways of modifying a parameter’s value using parameter expansion. A few of them are listed below with an explanation for your convenience.

Syntax Explanation
${parameter/#pattern/string} If pattern matches at the beginning of parameter, it is replaced with string.
${parameter/%pattern/string} If pattern matches at the end of parameter, it is replaced with string.
${parameter,pattern} If the value of the parameter starts with pattern, convert the first character to lowercase if it’s uppercase.
${parameter,,pattern} If the value of the parameter starts with pattern, convert all characters to lowercase if they are uppercase.
${parameter^pattern} If the value of the parameter starts with pattern, convert the first character to uppercase if it’s lowercase.
${parameter^^pattern} If the value of the parameter starts with pattern, convert all characters to uppercase if they are lowercase.
${parameter:start} Substring will retrieve from start position to the remaining part of the parameter.
${#parameter} Count the length of the parameter.
${parameter#pattern} Remove the shortest match from the beginning of the parameter where the pattern matches.
${parameter##pattern} Remove the longest match from the beginning of the parameter where the pattern matches.
${parameter%pattern} Remove the shortest match from the end of the parameter where the pattern matches.
${parameter%%pattern} Remove the longest match from the end of the parameter where the pattern matches.
${parameter/pattern/string} Replace the part of the parameter with string where the pattern match for the first time.
${parameter//pattern/string} Replace all occurrences in the parameter with string where all pattern matches.

Parameter Expansion Within a Bash Script

Bash users often face challenges to expand parameters using parameter expansion within a Bash script. Here I am showing you how to do this effectively:

#!/bin/bash

text="Bash Scripting"
task="${text:5}"    # Outputs: "Scripting"
shell= "${text:0:4}"  # Outputs: "Bash"
echo "I love ${task} in  ${shell}
EXPLANATION

The script begins with the shebang, #!/bin/bash, specifying that the script should be executed using the Bash shell. Then it sets the value of the variable “text” to “Bash Scripting”. It then uses parameter expansion to create two new variables task and shell by extracting substrings “Scripting” and “Bash” using the syntax ${text:5} and ${text:0:4} respectively. Finally, it prints a message, “I love Scripting in Bash” using these variables.

Parameter expansion in a Bash script

When executed the script prints “I love Scripting in Bash”. The words “Scripting” and “Bash” are extracted from the “text” variable using parameter expansion.

Conclusion

In conclusion, parameter expansion is an easy and efficient technique in Bash. Its built-in syntax and modifiers make the modification of a parameter’s value fairly simple. I believe this article has clearly imprinted the tricks of parameter expansion in your mind.

People Also Ask

What is parameter expansion in Bash?

Parameter expansion in Bash is the mechanism to refer to or manipulate variables and other parameters. It allows you to extract substrings, change cases, or other operations by referring to the value stored in the variables.

What is the difference between “${}” and “$()” syntax in Bash?

Primarily, “${}” expands a parameter or the value of a variable, while “$()” is used for command substitution. For example, ${variable} retrieves the value of the variable enclosed in curly braces, but “$()” captures the output of a command and stores it in a variable. It’s important to note that curly braces are not mandatory for parameter expansion; “$variable” will expand the parameter in the same way as ${variable}.

Why substring expansion is better than other commands for similar tasks?

Substring expansion is often considered an efficient way to manipulate variables compared to other string manipulation commands like awk or sed. It has built-in syntax, such as ${variable//search/replace} and ${variable%pattern}, along with greedy modifiers like “##” or “%%”, that can perform string operations with less code. Additionally, one can use wildcards to match patterns in substring expansion. It’s important to note that these wildcards are not the same as regular expressions used in sed or awk.

Is parameter expansion limited to Bash shell only?

No. Parameter expansion is not limited to the Bash shell only. Most of the modifications available for parameter expansion in Bash also work in other shells, such as zsh. Essentially, the modifiers for parameter expansion work in any shell that conforms to the POSIX standard.

How to use operator parameter expansion using “${parameter@operator}” syntax?

“@” syntax is used to use operator parameter expansion in Bash. There are a handsome amount of operators in Bash such as “U”, “L” and “Q” etc that are used to yield quick results of string manipulation. For instance, if there is a variable name= “Jhon”, “${name@U}” will expand to “JHON”.

Does Bash shell support nested parameter expansion?

No. You can’t achieve nested parameter expansion in Bash. For instance, you can’t set a default value for a parameter and capitalize it in a single parameter expansion. user=${user^^:=Jhon} will not work. Rather you can use parameter expansion multiple times. user=${user:=Jhon} and user=${user^^} can combinedly provide the desired output of user=${user^^:=Jhon}.

What is colon operator in bash parameter expansion?

Colon (:) operator in bash parameter expansion is used to modify or extract substrings. It modifies or extracts parts from the value of a parameter. For instance, ${parameter:start} syntax will retrieve the substring from the start position to the remaining part of the parameter.


Related Articles


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

5/5 - (7 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

Leave a Comment