Skip to content
shellhacks.dev

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.

Go deeper

Suggested reading

Keep planning

Similar tools