Bash Parameter Expansion
Parameter expansion reshapes a variable value while Bash reads it. It sets defaults, trims text, replaces words, and measures length without calling outside tools. The syntax uses curly braces: ${variable} with a special symbol inside.
Picture the Idea
file="report_final.txt"
${file} --> report_final.txt (plain value)
${#file} --> 16 (length)
${file%.txt} --> report_final (cut the ending)
${file/final/v2} --> report_v2.txt (swap a word)
Default Values
| Form | Result |
|---|---|
| ${name:-Guest} | Use Guest when name is empty or unset |
| ${name:=Guest} | Use Guest and also store it in name |
| ${name:+Member} | Use Member only when name has a value |
| ${name:?Missing} | Stop with an error message when name is empty |
#!/bin/bash
user=${1:-Guest}
echo "Welcome, $user"Running the script with no argument prints Welcome, Guest.
String Length
word="Bash"
echo ${#word}The output is 4.
Cut a Piece of Text
The form ${variable:start:length} counts from zero.
text="Hello World"
echo ${text:0:5} # Hello
echo ${text:6} # World
echo ${text: -5} # World (count from the end)Remove a Pattern From the Start or End
The hash symbol trims the beginning. The percent symbol trims the end. One symbol removes the shortest match, and two symbols remove the longest match.
path="/home/asha/photo.tar.gz"
echo ${path%.gz} # /home/asha/photo.tar
echo ${path%%.*} # /home/asha/photo
echo ${path#*/} # home/asha/photo.tar.gz
echo ${path##*/} # photo.tar.gzThe last line mimics the basename command and returns only the file name.
Replace Text
sentence="red apple, red cherry"
echo ${sentence/red/green} # green apple, red cherry
echo ${sentence//red/green} # green apple, green cherryOne slash replaces the first match. Two slashes replace every match.
Change Letter Case
Bash 4 or higher supports case conversion:
name="asha sharma"
echo ${name^} # Asha sharma
echo ${name^^} # ASHA SHARMA
word="BASH"
echo ${word,,} # bashPractical Example: Rename Many Files
This script changes every .txt file to .md:
#!/bin/bash
for file in *.txt
do
mv "$file" "${file%.txt}.md"
doneThe expression ${file%.txt} removes the old ending, and the script adds the new one.
Practical Example: Split a Path
#!/bin/bash
full="/var/log/app/server.log"
name=${full##*/}
folder=${full%/*}
echo "Name: $name"
echo "Folder: $folder"Output:
Name: server.log
Folder: /var/log/appIndirect Reference
An exclamation mark reads a variable whose name sits inside another variable:
color="red"
red="#FF0000"
echo ${!color}The output is #FF0000.
Practical Example: Safe Folder Variable
A missing variable can turn a delete command into a disaster. The error form of expansion stops the script before harm happens.
#!/bin/bash
backup_dir=${BACKUP_DIR:?Set BACKUP_DIR before running}
echo "Cleaning $backup_dir"
rm -f "$backup_dir"/*.tmpThe script prints the message and exits when BACKUP_DIR is empty. Without the check, the path would shrink to /*.tmp and touch files at the top of the system.
Expansion Compared With External Tools
| Task | External Tool | Expansion |
|---|---|---|
| Get file name | basename "$path" | ${path##*/} |
| Get folder | dirname "$path" | ${path%/*} |
| Count characters | echo "$s" | wc -c | ${#s} |
| Uppercase text | echo "$s" | tr a-z A-Z | ${s^^} |
Expansion avoids starting a new process, so loops with thousands of lines finish much faster.
Key Takeaways
${var:-default}supplies a fallback value.${#var}returns the length.${var:start:length}extracts part of a string.#trims from the front and%trims from the back.${var/old/new}replaces text, and a double slash replaces all matches.- Expansion runs inside Bash, so it is faster than calling
sedorcutin a loop.
