Skip to content

Variables in bash

  • Default value ${var:-default}
  • Default value ${var:=default}
  • Display an error message if parameter is not set ${var:?"Error"}
  • Lenght ${#var}
  • Find and replace ${var/find/replace}
  • Find and replace all occurences ${var//find/replace}
  • Remove from shortest front pattern ${var#pattern}
  • Remove from longest front pattern ${var##pattern}
  • Remove from shortest back pattern ${var%pattern}
  • Remove from longest back pattern ${var%%pattern}
  • Substring ${var:offset:lenght}
  • Capitalize word ${var^}
  • Capitalize if first character is m ${var^m}
  • Uppercase ${var^^}
  • Uppercase all m ${var^^m}
  • Lowercase first character ${var,}
  • Lowercase ${var,,}
  • Lowercase first character if it is M ${var,M}
  • Lowercase all M ${var,,M}

Substitution

Substitute : for ;:

var="1:2:3:67:23:67"
${var//:/;}

Substring (Slicing)

${var:offset:lenght}
u@h ~> var="2022/07/03"
u@h ~> echo ${var:8}
03
u@h ~> echo ${var:0:4}
2022
u@h ~> echo ${var:5:2}
07

Default variable

Set variable weather to sunny if variable weather does not exist or is empty:

u@h ~> var=${weather:-sunny}
u@h ~> echo $var
sunny
u@h ~> weather="rainy"
u@h ~> var=${weather:-sunny}
u@h ~> echo $var
rainy
u@h ~> weather=""
u@h ~> var=${weather:-sunny}
u@h ~> echo $var
sunny

The same but with := istead of :-

u@h ~> var=${weather:=sunny}
u@h ~> echo $var
sunny
u@h ~> weather="rainy"
u@h ~> var=${weather:=sunny}
u@h ~> echo $var
rainy
u@h ~> weather=""
u@h ~> var=${weather:=sunny}
u@h ~> echo $var
sunny

The only difference between :- and := is that := does not work with positional arguments.

Error if unset

weather="sunny"
u@h ~> echo ${weather?Error weather is not defined}
sunny
u@h ~> unset weather
u@h ~> echo ${weather?"Error weather is not defined"}
bash: weather: Error weather is not defined

You can use a variable to define the message. zsh does not seem to like it.

u@h ~> message="Not defined"
u@h ~> echo ${weather?"Error: ${message}"}
bash: weather: "Error: ${message}"

Remove pattern

  • ${var#pattern} Shortest part of pattern at the front.
  • ${var##pattern} Longest part of pattern at the front. Useful to grab the file name from the full path.

Example

u@h ~> var="/home/user/.local/share/Trash/files/notes.txt"

u@h ~> echo "${var#.}"
/home/user/.local/share/Trash/files/notes.txt
u@h ~> echo "${var#.*}"
/home/user/.local/share/Trash/files/notes.txt
u@h ~> echo "${var#*.}"
local/share/Trash/files/notes.txt
u@h ~> echo "${var#*.*}"
local/share/Trash/files/notes.txt

u@h ~> echo "${var#/}"
home/user/.local/share/Trash/files/notes.txt
u@h ~> echo "${var#*/}"
home/user/.local/share/Trash/files/notes.txt
u@h ~> echo "${var#/*}"
home/user/.local/share/Trash/files/notes.txt
u@h ~> echo "${var#*/}"
home/user/.local/share/Trash/files/notes.txt
u@h ~> echo "${var##/}"
home/user/.local/share/Trash/files/notes.txt
u@h ~> echo "${var##*/}"
notes.txt
u@h ~> echo "${var##/*}"
## Nothing
  • ${var%pattern} Shortest part of pattern at the back.
  • ${var%%pattern} Shortest part of pattern at the back. Useful to remove file extensions.

Example

u@h ~> var="backup.tar.gz.sha256.gpg"
u@h ~> echo "${var%.}"
backup.tar.gz.sha256.gpg
u@h ~> echo "${var%*.}"
backup.tar.gz.sha256.gpg
u@h ~> echo "${var%.*}"
backup.tar.gz.sha256
u@h ~> echo "${var%*.*}"
backup.tar.gz.sha256
u@h ~> echo "${var%%.}"
backup.tar.gz.sha256.gpg
u@h ~> echo "${var%%*.}"
backup.tar.gz.sha256.gpg
u@h ~> echo "${var%%.*}"
backup
u@h ~> echo "${var%%*.*}"
## Nothing

Find and replace

First occurrence

u@h ~> var="find the word find in var"
u@h ~> echo ${var/find/replace}
replace the word find in var

All occurrences

u@h ~> var="find the word find in var"
u@h ~> echo ${var//find/replace}
replace the word replace in var

Sources