String Manipulation
Prerequisites: Variables
Bash's parameter expansion operators transform strings without calling external programs — fast, and handy for file names and paths.
Length, substrings, and case
text="Hello, World"
echo "${#text}"
echo "${text:0:5}"
echo "${text:7}"
echo "${text^^}"
echo "${text,,}"
12
Hello
World
HELLO, WORLD
hello, world
${#var}— length.${var:start:length}— substring (positions from 0).${var^^}/${var,,}— upper / lower case (Bash 4+).
Removing prefixes and suffixes
path="/home/ada/photos/beach.holiday.jpg"
echo "${path##*/}"
echo "${path%/*}"
echo "${path%.*}"
echo "${path%%.*}"
echo "${path##*.}"
beach.holiday.jpg
/home/ada/photos
/home/ada/photos/beach.holiday
/home/ada/photos/beach
jpg
| Syntax | Removes |
|---|---|
${var#pattern} |
shortest match from the start |
${var##pattern} |
longest match from the start |
${var%pattern} |
shortest match from the end |
${var%%pattern} |
longest match from the end |
So ${path##*/} is the file name (like basename), ${path%/*} the
folder (like dirname), and ${path##*.} the extension.
Replacing
file="my holiday photo.jpg"
echo "${file/ /_}"
echo "${file// /_}"
echo "${file/%jpg/png}"
my_holiday photo.jpg
my_holiday_photo.jpg
my holiday photo.png
${var/old/new} replaces the first match; ${var//old/new} replaces all;
/% anchors the match to the end.
Defaults and required values
unset color
echo "${color:-blue}"
echo "color is still: '${color}'"
echo "${color:=green}"
echo "color is now: '${color}'"
blue
color is still: ''
green
color is now: 'green'
${var:-default}— use a default if unset or empty.${var:=default}— also assign the default.${var:?message}— stop with an error if unset or empty — useful for required settings.
Practice
Given file="report.final.pdf", print the name without its extension and
the extension on its own.
Show solution
file="report.final.pdf"
echo "${file%.*}"
echo "${file##*.}"
report.final
pdf