Skip to content
AgileLogics
6 min read

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