Bash Parameter Substitution

Bash Parameter Substitution
Table 1: Bash Parameter Substitution
Variable Description
${parameter:-defaultValue} Get default shell variables value
${parameter:=defaultValue} Set default shell variables value
${parameter:?"Error Message"} Display an error message if parameter is not set
${#var} Find the length of the string
${var%pattern} Remove from shortest rear (end) pattern
${var%%pattern} Remove from longest rear (end) pattern
${var:num1:num2} Substring
${var#pattern} Remove from shortest front pattern
${var##pattern} Remove from longest front pattern
${var/pattern/string} Find and replace (only replace first occurrence)
${var//pattern/string} Find and replace all occurrences
${!prefix*} Expands to the names of variables whose names begin with prefix.
${var,}
${var,pattern}
Convert first character to lowercase.
${var,,}
${var,,pattern}
Convert all characters to lowercase.
${var^}
${var^pattern}
Convert first character to uppercase.
${var^^}
${var^^pattern}
Convert all character to uppercase.

The $ character is used for parameter expansion, arithmetic expansion and command substitution. You can use it for manipulating and expanding variables on demands without using external commands such as perl, python, sed or awk. This guide shows you how to use parameter expansion modifiers to transform Bash shell variables for your scripting needs.

Syntax

You can use variables to store data and configuration options. For example:

~] dir="/ftp"

# Use echo or printf command to display variable value:
~] echo "$dir"
/ftp

# or
~] printf "$dir\n"
/ftp

# The parameter name or symbol such as $dest to be expanded may be enclosed in braces
~] echo "Value: ${dir}"
Value: /ftp

Setting Up Default Shell Variables Value

The syntax is as follows:

${parameter:-defaultValue}
var=${parameter:-defaultValue}

If parameter not set, use defaultValue. In this example, your shell script takes arguments supplied on the command line. You'd like to provide default value so that the most common value can be used without needing to type them every time. If variable $1 is not set or passed, use John as default value for user variable:

user=${1:-John}

Example:

~] city=${1:-Paris}
~] echo $city
Paris

# or

~] echo "${city}"
Paris

Setting Default Values

The syntax is as follows:

${var:=value}
var=${USER:=value}

The assignment := operator is used to assign a value to the variable if it doesn't already have one. Try the following examples:

~] echo $TERM
linux

# Now, assign a value foo to the $TERM variable if doesn't already have one:
# TERM variable has a value, no print change  
~] echo ${TERM:=vty100}
linux

# unset TERM variable and print now:
~] unset TERM
~] echo ${TERM:=vty100}
vty100

var=${1:=defaultValue}  ### FAIL with an error cannot assign in this way
var=${1:-defaultValue}  ### Perfect

Display an Error Message If $VAR Not Passed

If the variable is not defined or not passed, you can stop executing the Bash script with the following syntax:

${varName?Error varName is not defined}
${varName:?Error varName is not defined or is empty}
${1:?"example1.sh: Missing operand"}
MESSAGE="Usage: example1.sh domainname IPv4"   ### define error message
_domain=${2?"Error: ${MESSAGE}"}               ### you can use $MESSAGE too

example 1:

~] cat example.sh
varName="abc"

#!/bin/bash

# print error message when we want use undefined variable
_var1=${varName?Error varName is not defined}
_var2=${varName:?Error varName is not defined or is empty}
_domn=${1:?"example.sh: Missing domain operand"}
MESSAGE="Usage: example.sh domainname IPv4"   ### define error message
_ipv4=${2?"Error: ${MESSAGE}"}                ### you can use $MESSAGE too

echo "${_var1}, ${_var2}, ${_domn}, ${_ipv4}"

# run script
~] ./example.sh 
./example.sh: řádek 4: varName: Error varName is not defined 

example 2:

~] cat example.sh
#!/bin/bash

varName=""

# print error message when we want use undefined variable
_var1=${varName?Error varName is not defined}
_var2=${varName:?Error varName is not defined or is empty}
_domn=${1:?"example.sh: Missing domain operand"}
MESSAGE="Usage: example.sh domainname IPv4"   ### define error message
_ipv4=${2?"Error: ${MESSAGE}"}                ### you can use $MESSAGE too

echo "${_var1}, ${_var2}, ${_domn}, ${_ipv4}"

# run script
~] ./example.sh 
./example.sh: řádek 7: varName: Error varName is not defined or is empty  

example 3:

~] cat example.sh
#!/bin/bash

varName="abc"

# print error message when we want use undefined variable
_var1=${varName?Error varName is not defined}
_var2=${varName:?Error varName is not defined or is empty}
_domn=${1:?"example.sh: Missing domain operand"}
MESSAGE="Usage: example.sh domainname IPv4"   ### define error message
_ipv4=${2?"Error: ${MESSAGE}"}                ### you can use $MESSAGE too

echo "${_var1}, ${_var2}, ${_domn}, ${_ipv4}"

# run script
~] ./example.sh 
./example.sh: řádek 8: 1: example.sh: Missing domain operand

example 4 and 5:

~] ./example.sh www.test.cz
./example.sh: řádek 10: 2: Error: Usage: example.sh domainname IPv4

~] ./example.sh www.test.cz 127.0.0.1
abc, abc, www.test.cz, 127.0.0.1

Find Bash Variable Length

You can easily find string length using the following syntax:

${#variableName}
echo "${#variableName}"
len="${#var}"
# print it 
echo "$len"

example:

~] cat example.sh
#!/bin/bash

_user="$1"
_pass="$2"

echo "${#_user}"

len="${#_pass}"
echo "${len}"

# run script
~] ./example.sh user password
4
8

Remove Pattern (Front of $VAR)

The syntax is as follows:

try to remove shortest part of $_url

~] _url="https://www.mybluelinux.com/what-is-email-envelope-and-email-header/"
~] echo "${_url#*/}"
/www.mybluelinux.com/what-is-email-envelope-and-email-header/

Now try using the longest part of the pattern syntax:

~] _url="https://www.mybluelinux.com/what-is-email-envelope-and-email-header/index.html"
~] echo "${_url##*/}"
index.html

Get filename without using basename command:

~] file="/home/username/dir1/dir2/filename.tar.gz"
~] echo ${file##*/}
filename.tar.gz

Get running script name using bash parameter - The $0 will provide full path for currently running script. To extract that name only:

#!/bin/bash

_self="${0##*/}"
echo "$_self is called"
 
## or in usage() ##
usage(){
    echo "$_self: arg1 arg2"
}

Remove Pattern (Back of $VAR)

The syntax is as follows:

examples:

~] _url="https://www.mybluelinux.com/what-is-email-envelope-and-email-header/index.html"
~] echo "${_url%*/}"
https://www.mybluelinux.com/what-is-email-envelope-and-email-header/index.html

~] _url="https://www.mybluelinux.com/what-is-email-envelope-and-email-header/index.html"
~] echo "${_url%%/*}"
https:
~] file="/home/username/dir1/dir2/filename.tar.gz"
~] echo ${file%/*}
/home/username/dir1/dir2

Find And Replace

The syntax is as follows:

${varName/Pattern/Replacement}
${varName/word1/word2}
${os/Unix/Linux}

Find word unix and replace with linux, enter:

~] x="Use unix and only unix or die"
~] sed 's/unix/linux/' <<<$x
Use linux and only unix or die

You can avoid using sed as follows:

~] x="Use unix and only unix or die"
~] echo "${x/unix/linux}"
Use linux and only unix or die

To replace all matches of pattern, enter:

~] x="Use unix and only unix or die"
~] echo "${x//unix/linux}"
Use linux and only linux or die
~] echo "${x//[ux]/A}"
Use AniA and only AniA or die

Substring Starting Character

The syntax is as follows:

${parameter:offset}
${parameter:offset:length}
${variable:position}
var=${string:position}

Expands to up to length characters of parameter starting at the character specified by offset.

~] base="/backup/nas"
~] file="/data.tar.gz"
~] path="${base}/${file:1}"
~] echo "${path}"
/backup/nas/data.tar.gz

strip some chars:

~] x="mybluelinux.com"
~] echo "${x:1}"
ybluelinux.com
~] echo "${x:2}"
bluelinux.com
~] echo "${x:0:3}"
myb
~] echo "${x:2:6}"
blueli

Get list of matching variable names

~] var1="a"
~] var2="b"
~] var3="c"
~] xyz1="d"
~] echo "${!var*}"
var1 var2 var3

Convert bash variable to upper to lower case or vice versa

uppercase:

~] _url="https://www.mybluelinux.com/čšďá.html"

# only first character to uppercase
~] echo "${_url^}" 
Https://www.mybluelinux.com/čšďá.html

# all characters to uppercase
~] echo "${_url^^}" 
HTTPS://WWW.MYBLUELINUX.COM/ČŠĎÁ.HTML

# another examples
~] name="john"
~] echo "Hi ${name}"
Hi john
~] echo "Hi ${name^}"
Hi John
~] echo "Hi ${name^^}"
Hi JOHN

lowercase:

~] name="ALBERT EINSTEIN"
~] echo "Hi ${name}"
Hi ALBERT EINSTEIN
~] echo "Hi ${name,}"
Hi aLBERT EINSTEIN
~] echo "Hi ${name,,}"
Hi albert einstein
~] echo "Hi ${name,,I}"
Hi ALBERT EiNSTEiN

SUBSCRIBE FOR NEW ARTICLES

@
comments powered by Disqus