Skip to content
Linux Basics: Transform Text with Bash Parameter Expansion

Linux Basics: Transform Text with Bash Parameter Expansion

October 18, 2026

Bash can supply defaults and reshape strings without launching another program. Parameter expansion is especially handy for small, predictable pieces of text inside a script.

These examples were tested on Linux with GNU Bash 5.2.37. Use Bash rather than sh; some syntax is Bash-specific. No packages or administrator access are needed.

Prepare a scratch directory

You need Bash, a text editor, and the mktemp, rm, and rmdir utilities. Keep using the same terminal. The guards stop the shell if setup fails. Save each named source file in this directory before running its command. Calling bash explicitly means you do not need to change executable permissions.

start_dir="$PWD"
work_dir="$(mktemp -d)" || exit 1
cd -- "$work_dir" || exit 1

1. Choose defaults for missing text

Save this as expansion-defaults.sh:

#!/usr/bin/env bash
unset nickname
printf 'Unset: %s\n' "${nickname:-guest}"
nickname=''
printf 'Empty with colon: %s\n' "${nickname:-guest}"
printf 'Empty without colon: <%s>\n' "${nickname-guest}"
printf 'Still empty: <%s>\n' "$nickname"

Run it:

bash expansion-defaults.sh

Output:

Unset: guest
Empty with colon: guest
Empty without colon: <>
Still empty: <>

:- substitutes a fallback when a variable is unset or empty. - substitutes only when it is unset. Neither assigns the fallback to the variable. Quoting the complete expansion preserves the resulting text as one argument.

2. Remove a path prefix and suffix

Save this as expansion-paths.sh:

#!/usr/bin/env bash
path='reports/monthly.summary.csv'
filename=${path##*/}
stem=${filename%.*}
printf 'Filename: %s\n' "$filename"
printf 'Stem: %s\n' "$stem"
printf 'First-dot stem: %s\n' "${filename%%.*}"

Run it:

bash expansion-paths.sh

Output:

Filename: monthly.summary.csv
Stem: monthly.summary
First-dot stem: monthly

## removes the longest matching prefix, while % removes the shortest matching suffix and %% the longest. These use shell patterns, not regular expressions. Here the last slash and last dot delimit useful parts of a known filename. This is text processing only: it does not check whether the path exists or cover every naming convention.

3. Replace text and take a slice

Save this as expansion-text.sh:

#!/usr/bin/env bash
title='weekly status update'
printf 'First replacement: %s\n' "${title/ /-}"
printf 'All replacements: %s\n' "${title// /-}"
printf 'Length: %s\n' "${#title}"
printf 'Slice: %s\n' "${title:7:6}"

Run it:

bash expansion-text.sh

Output:

First replacement: weekly-status update
All replacements: weekly-status-update
Length: 20
Slice: status

A single slash replaces the first match; two replace every match. The pattern here is one literal space. ${#title} gives the string length and ${title:7:6} takes six characters starting at zero-based offset seven. This example uses ASCII so the output is independent of multibyte character handling.

Clean up

In the same terminal, remove only the example files, return to your original directory, and remove the empty scratch directory:

rm -- expansion-defaults.sh expansion-paths.sh expansion-text.sh
cd -- "$start_dir" || exit 1
rmdir -- "$work_dir"
unset start_dir work_dir

Reference

The GNU Bash manual: Shell Parameter Expansion documents the syntax used here.

Acknowledgements

This post was created with assistance from AI.

Last updated on