C.W.K.
Stream
Lesson 02 of 05 · published

Parameter Expansion Advanced

~13 min · parameter-expansion, default, substitute

Level 0Window Tourist
0 XP0/95 lessons0/14 achievements
0/100 XP to next level100 XP to go0% complete

The expansion forms you'll use forever

Bash and zsh share a rich parameter-expansion language. Once these patterns are in your fingers, you stop reaching for sed for half of the tiny manipulations.

Defaults

  • ${var:-default} — value of var, or default if unset/empty.
  • ${var:=default} — same, but also assign the default.
  • ${var:+alt} — alt if var is set, else empty. Inverse.
  • ${var:?error} — exit with error if unset/empty. Great for required env vars.

Length

${#var}                    # string length
${#arr[@]}                 # array length

Substring

${var:5}                  # from char 5 to end
${var:5:3}                # 3 chars starting at 5
${var: -4}                # last 4 chars (note the space!)

Trim from front

  • ${var#prefix} — strip shortest match of prefix glob.
  • ${var##prefix} — strip longest.
path=/usr/local/bin
echo ${path#*/}            # usr/local/bin
echo ${path##*/}           # bin             (basename!)

Trim from back

  • ${var%suffix} — strip shortest match of suffix.
  • ${var%%suffix} — strip longest.
file=foo.tar.gz
echo ${file%.gz}           # foo.tar
echo ${file%%.*}           # foo

Substitution

  • ${var/from/to} — first match.
  • ${var//from/to} — every match.
  • ${var/#from/to} — only at the start.
  • ${var/%from/to} — only at the end.

Case

${var^^}                  # uppercase (bash 4+)
${var,,}                  # lowercase
${var^}                   # capitalize first letter

Why memorize

These run inside the shell with no fork — orders of magnitude faster than spawning sed/awk for the same job. Most one-line text manipulation in shell can be done with parameter expansion alone.

Code

Real-life one-liners·bash
file=/path/to/document.tar.gz
echo "${file##*/}"      # document.tar.gz   (basename)
echo "${file%/*}"       # /path/to          (dirname)
echo "${file%.gz}"      # /path/to/document.tar
echo "${file%%.*}"      # /path/to/document
name=pippa
echo "${name^^}"       # PIPPA

External links

Exercise

Set path=/Users/me/notes/idea.md. Run all five expansions: ${path##*/}, ${path%/*}, ${path%.md}, ${path//\//-}, ${#path}. Memorize the three you use most — usually basename, dirname, suffix-strip.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.