We discussed this already in Section 4.6, “Arithmetic expansion”.
Using the ${#VAR
} syntax will calculate the number of characters in a variable. If VAR
is “*” or “@”, this value is substituted with the number of positional parameters or number of elements in an array in general. This is demonstrated in the example below:
[bob in ~]
echo$SHELL
/bin/bash[bob in ~]
echo${#SHELL}
9[bob in ~]
ARRAY
=(one two three)
[bob in ~]
echo${#ARRAY}
3
${
VAR
:-WORD
}
If VAR
is not defined or null, the expansion of WORD
is substituted; otherwise the value of VAR
is substituted:
[bob in ~]
echo${TEST:-test}
test[bob in ~]
echo$TEST
[bob in ~]
exportTEST
=a_string
[bob in ~]
echo${TEST:-test}
a_string[bob in ~]
echo${TEST2:-$TEST}
a_string
This form is often used in conditional tests, for instance in this one:
[ -z "${COLUMNS:-}" ]
&& COLUMNS
=80
It is a shorter notation for
if [ -z "${COLUMNS:-}" ]
; then
COLUMNS
=80
fi
See Section 1.2.3, “String comparisons” for more information about this type of condition testing.
If the hyphen (-) is replaced with the equal sign (=), the value is assigned to the parameter if it does not exist:
[bob in ~]
echo$TEST2
[bob in ~]
echo${TEST2:=$TEST}
a_string[bob in ~]
echo$TEST2
a_string
The following syntax tests the existence of a variable. If it is not set, the expansion of WORD
is printed to standard out and non-interactive shells quit. A demonstration:
[bob in ~]
catvartest.sh
#!/bin/bash # This script tests whether a variable is set. If not, # it exits printing a message. echo ${TESTVAR:?"There's so much I still wanted to do..."} echo "TESTVAR is set, we can proceed."[bob in testdir]
./vartest.sh ./vartest.sh: line 6: TESTVAR: There's so much I still wanted to do...[bob in testdir]
exportTESTVAR
=present
[bob in testdir]
./vartest.sh present TESTVAR is set, we can proceed.
Using “+” instead of the exclamation mark sets the variable to the expansion of WORD
; if it does not exist, nothing happens.
To strip a number of characters, equal to OFFSET
, from a variable, use this syntax:
${
VAR
:OFFSET
:LENGTH
}
The LENGTH
parameter defines how many characters to keep, starting from the first character after the offset point. If LENGTH
is omitted, the remainder of the variable content is taken:
[bob in ~]
exportSTRING
="thisisaverylongname"
[bob in ~]
echo${STRING:4}
isaverylongname[bob in ~]
echo${STRING:6:5}
avery
${
VAR
#WORD
}
and
${
VAR
##WORD
}
These constructs are used for deleting the pattern matching the expansion of WORD
in VAR
. WORD
is expanded to produce a pattern just as in file name expansion. If the pattern matches the beginning of the expanded value of VAR
, then the result of the expansion is the expanded value of VAR
with the shortest matching pattern (“#”) or the longest matching pattern (indicated with “##”).
If VAR
is *
or @
, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list.
If VAR
is an array variable subscribed with “*” or “@”, the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list. This is shown in the examples below:
[bob in ~]
echo${ARRAY[*]}
one two one three one four[bob in ~]
echo${ARRAY[*]#one}
two three four[bob in ~]
echo${ARRAY[*]#t}
one wo one hree one four[bob in ~]
echo${ARRAY[*]#t*}
one wo one hree one four[bob in ~]
echo${ARRAY[*]##t*}
one one one four
The opposite effect is obtained using “%” and “%%”, as in this example below. WORD
should match a trailing portion of string:
[bob in ~]
echo$STRING
thisisaverylongname[bob in ~]
echo${STRING%name}
thisisaverylong
This is done using the
${
VAR
/PATTERN
/STRING
}
or
${
VAR
//PATTERN
/STRING
}
syntax. The first form replaces only the first match, the second replaces all matches of PATTERN
with STRING
:
[bob in ~]
echo${STRING/name/string}
thisisaverylongstring
More information can be found in the Bash info pages.