FUNDAMENTALS A Complete Guide for Beginners
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}
In 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}
In 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.
${!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.Now, 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
At 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.There 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}
Here 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^}
Here, ${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.In 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.In the above image, ${user,}
converts the first character of the user parameter to lowercase, making the value change from ANDREW to aNDREW.The 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}
In 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}
In 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.
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}
${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/}
${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}
${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#*/}
Here, ${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##*/}"
Here 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%/*}"
Here 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%%/*}"
The 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}
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.
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
- How to Use Brace Expansion in Bash Scripting [3 Cases]
- How to Use Tilde Expansion in Bash [4 Practical Cases]
- Arithmetic Expansion in Bash [3 Practical Applications]
- An Exhaustive Guide to Bash History Expansion
- What is Array Expansion in Bash [4 Useful Applications]
- Glob Expansion in Bash
<< Go Back to An Overview of Shell Expansion in Bash | Bash Scripting Tutorial