Skip to content
gohacks.dev
Tooling

Bash Parameter Expansion

A cheat sheet of bash parameter expansion: defaults, required variables, length, prefix and suffix removal, search and replace, substrings, case conversion, indirection and special parameters.

Free · No sign-up · Your inputs stay in your browser

Reference

Bash parameter expansion

SyntaxGivesExample and notes
${var:-default}var, or default if unset or empty${var-default} only when unset.
${var:=default}Same, and assign default to var
${var:?message}Exit with message if unset or emptyGuards required arguments: ${1:?usage: deploy ENV}.
${var:+other}other if var is set, else nothingAdds a flag only when needed: ${DEBUG:+--verbose}.
${#var}Length of the value${#arr[@]} is the number of array elements.
${var#pattern}Remove the shortest match from the start${path#*/}
${var##pattern}Remove the longest match from the start${path##*/} is basename.
${var%pattern}Remove the shortest match from the end${file%.*} drops the extension; ${path%/*} is dirname.
${var%%pattern}Remove the longest match from the end${version%%.*} is the major version.
${var/old/new}Replace the first match
${var//old/new}Replace every match${PATH//:/$'\n'} prints PATH one entry per line.
${var/#old/new} ${var/%old/new}Replace only at the start, or the end
${var:offset:length}Substring${var: -4} takes the last four (the space matters).
${var^} ${var^^}Uppercase first letter, all lettersbash 4+.
${var,} ${var,,}Lowercase first letter, all lettersbash 4+.
${!name}Indirection: the value of the variable named by name
${!prefix@}Names of variables starting with prefix${!DB_@}
${var@Q}Value quoted for reuse as shell inputbash 4.4+.
${arr[@]} ${arr[*]}All elementsQuote "${arr[@]}" to keep elements with spaces intact.
${!arr[@]}All indexes or keys
$(( 2 ** 10 ))Integer arithmeticNo floats: use bc or awk.
$? $! $$Last exit status, last background PID, this shell's PID
$# $@ $0Argument count, all arguments, script name"$@" keeps each argument separate; $* joins them.

Expansions run inside the shell, so they are faster than calling sed, basename or tr in a loop. Patterns are globs, not regular expressions. The ^ and , case operators need bash 4 or later, which macOS's /bin/bash (3.2) is not; brew install bash, or use zsh, which has its own flags.

Faster than calling tools

Expansions run inside the shell, so ${file%.*} to drop an extension or ${path##*/} for the basename is much faster in a loop than calling basename or sed thousands of times. The patterns are globs, not regular expressions. The bash manual's parameter expansion section covers each form.

Portability

Case conversion, @Q and some array forms need bash 4 or later. macOS's /bin/bash is version 3.2, so scripts that need them should require a newer bash or be written for zsh, which has its own flags.

Share

Frequently asked questions

How do I set a default value for a variable in bash?
${VAR:-default} uses default when VAR is unset or empty; ${VAR:=default} also assigns it.
How do I get a file's extension in bash?
${file##*.} gives the extension and ${file%.*} the name without it.
Is what I paste sent anywhere?
No. The tool runs entirely in your browser with JavaScript. Nothing you type or paste is sent to our server or stored.

Keep planning

Similar tools