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 lengthSubstring
${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%%.*} # fooSubstitution
${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 letterWhy learn the forms
Parameter expansion avoids an external process and keeps small pathname or default-value operations local to the shell. Prefer it when the pattern is readable and the target shell supports it; use a dedicated text tool when records, encodings, or complex transformations make the contract clearer.
Patterns still have edge cases
The trim and substitution operands are shell patterns, and unquoted results can be split or expanded again. Quote expansions, test empty values and leading dots, and do not treat one expression as an exact replacement for every dirname or basename case.
Colon defaults and trim patterns are separate contracts
In forms such as ${var-default} and ${var:-default}, the colon decides whether an empty value counts like an unset one. In #, ##, %, and %% forms, the operand is a shell pattern rather than a literal substring. Test empty values and pattern characters explicitly.