bash: Shell Parameter Expansion

1 
1 3.5.3 Shell Parameter Expansion
1 -------------------------------
1 
1 The '$' character introduces parameter expansion, command substitution,
1 or arithmetic expansion.  The parameter name or symbol to be expanded
1 may be enclosed in braces, which are optional but serve to protect the
1 variable to be expanded from characters immediately following it which
1 could be interpreted as part of the name.
1 
1    When braces are used, the matching ending brace is the first '}' not
1 escaped by a backslash or within a quoted string, and not within an
1 embedded arithmetic expansion, command substitution, or parameter
1 expansion.
1 
1    The basic form of parameter expansion is ${PARAMETER}.  The value of
1 PARAMETER is substituted.  The PARAMETER is a shell parameter as
DONTPRINTYET 1 described above (⇒Shell Parameters) or an array reference (*note1DONTPRINTYET 1 described above (⇒Shell Parameters) or an array reference (⇒
 Arrays).  The braces are required when PARAMETER is a positional
1 parameter with more than one digit, or when PARAMETER is followed by a
1 character that is not to be interpreted as part of its name.
1 
1    If the first character of PARAMETER is an exclamation point (!), and
1 PARAMETER is not a NAMEREF, it introduces a level of variable
1 indirection.  Bash uses the value of the variable formed from the rest
1 of PARAMETER as the name of the variable; this variable is then expanded
1 and that value is used in the rest of the substitution, rather than the
1 value of PARAMETER itself.  This is known as 'indirect expansion'.  If
1 PARAMETER is a nameref, this expands to the name of the variable
1 referenced by PARAMETER instead of performing the complete indirect
1 expansion.  The exceptions to this are the expansions of ${!PREFIX*} and
1 ${!NAME[@]} described below.  The exclamation point must immediately
1 follow the left brace in order to introduce indirection.
1 
1    In each of the cases below, WORD is subject to tilde expansion,
1 parameter expansion, command substitution, and arithmetic expansion.
1 
1    When not performing substring expansion, using the form described
1 below (e.g., ':-'), Bash tests for a parameter that is unset or null.
1 Omitting the colon results in a test only for a parameter that is unset.
1 Put another way, if the colon is included, the operator tests for both
1 PARAMETER's existence and that its value is not null; if the colon is
1 omitted, the operator tests only for existence.
1 
1 '${PARAMETER:-WORD}'
1      If PARAMETER is unset or null, the expansion of WORD is
1      substituted.  Otherwise, the value of PARAMETER is substituted.
1 
1 '${PARAMETER:=WORD}'
1      If PARAMETER is unset or null, the expansion of WORD is assigned to
1      PARAMETER.  The value of PARAMETER is then substituted.  Positional
1      parameters and special parameters may not be assigned to in this
1      way.
1 
1 '${PARAMETER:?WORD}'
1      If PARAMETER is null or unset, the expansion of WORD (or a message
1      to that effect if WORD is not present) is written to the standard
1      error and the shell, if it is not interactive, exits.  Otherwise,
1      the value of PARAMETER is substituted.
1 
1 '${PARAMETER:+WORD}'
1      If PARAMETER is null or unset, nothing is substituted, otherwise
1      the expansion of WORD is substituted.
1 
1 '${PARAMETER:OFFSET}'
1 '${PARAMETER:OFFSET:LENGTH}'
1      This is referred to as Substring Expansion.  It expands to up to
1      LENGTH characters of the value of PARAMETER starting at the
1      character specified by OFFSET.  If PARAMETER is '@', an indexed
1      array subscripted by '@' or '*', or an associative array name, the
1      results differ as described below.  If LENGTH is omitted, it
1      expands to the substring of the value of PARAMETER starting at the
1      character specified by OFFSET and extending to the end of the
11      value.  LENGTH and OFFSET are arithmetic expressions (⇒Shell
      Arithmetic).
1 
1      If OFFSET evaluates to a number less than zero, the value is used
1      as an offset in characters from the end of the value of PARAMETER.
1      If LENGTH evaluates to a number less than zero, it is interpreted
1      as an offset in characters from the end of the value of PARAMETER
1      rather than a number of characters, and the expansion is the
1      characters between OFFSET and that result.  Note that a negative
1      offset must be separated from the colon by at least one space to
1      avoid being confused with the ':-' expansion.
1 
1      Here are some examples illustrating substring expansion on
1      parameters and subscripted arrays:
1 
1      $ string=01234567890abcdefgh
1      $ echo ${string:7}
1      7890abcdefgh
1      $ echo ${string:7:0}
1      
1      $ echo ${string:7:2}
1      78
1      $ echo ${string:7:-2}
1      7890abcdef
1      $ echo ${string: -7}
1      bcdefgh
1      $ echo ${string: -7:0}
1      
1      $ echo ${string: -7:2}
1      bc
1      $ echo ${string: -7:-2}
1      bcdef
1      $ set -- 01234567890abcdefgh
1      $ echo ${1:7}
1      7890abcdefgh
1      $ echo ${1:7:0}
1      
1      $ echo ${1:7:2}
1      78
1      $ echo ${1:7:-2}
1      7890abcdef
1      $ echo ${1: -7}
1      bcdefgh
1      $ echo ${1: -7:0}
1      
1      $ echo ${1: -7:2}
1      bc
1      $ echo ${1: -7:-2}
1      bcdef
1      $ array[0]=01234567890abcdefgh
1      $ echo ${array[0]:7}
1      7890abcdefgh
1      $ echo ${array[0]:7:0}
1      
1      $ echo ${array[0]:7:2}
1      78
1      $ echo ${array[0]:7:-2}
1      7890abcdef
1      $ echo ${array[0]: -7}
1      bcdefgh
1      $ echo ${array[0]: -7:0}
1      
1      $ echo ${array[0]: -7:2}
1      bc
1      $ echo ${array[0]: -7:-2}
1      bcdef
1 
1      If PARAMETER is '@', the result is LENGTH positional parameters
1      beginning at OFFSET.  A negative OFFSET is taken relative to one
1      greater than the greatest positional parameter, so an offset of -1
1      evaluates to the last positional parameter.  It is an expansion
1      error if LENGTH evaluates to a number less than zero.
1 
1      The following examples illustrate substring expansion using
1      positional parameters:
1 
1      $ set -- 1 2 3 4 5 6 7 8 9 0 a b c d e f g h
1      $ echo ${@:7}
1      7 8 9 0 a b c d e f g h
1      $ echo ${@:7:0}
1      
1      $ echo ${@:7:2}
1      7 8
1      $ echo ${@:7:-2}
1      bash: -2: substring expression < 0
1      $ echo ${@: -7:2}
1      b c
1      $ echo ${@:0}
1      ./bash 1 2 3 4 5 6 7 8 9 0 a b c d e f g h
1      $ echo ${@:0:2}
1      ./bash 1
1      $ echo ${@: -7:0}
1      
1 
1      If PARAMETER is an indexed array name subscripted by '@' or '*',
1      the result is the LENGTH members of the array beginning with
1      '${PARAMETER[OFFSET]}'.  A negative OFFSET is taken relative to one
1      greater than the maximum index of the specified array.  It is an
1      expansion error if LENGTH evaluates to a number less than zero.
1 
1      These examples show how you can use substring expansion with
1      indexed arrays:
1 
1      $ array=(0 1 2 3 4 5 6 7 8 9 0 a b c d e f g h)
1      $ echo ${array[@]:7}
1      7 8 9 0 a b c d e f g h
1      $ echo ${array[@]:7:2}
1      7 8
1      $ echo ${array[@]: -7:2}
1      b c
1      $ echo ${array[@]: -7:-2}
1      bash: -2: substring expression < 0
1      $ echo ${array[@]:0}
1      0 1 2 3 4 5 6 7 8 9 0 a b c d e f g h
1      $ echo ${array[@]:0:2}
1      0 1
1      $ echo ${array[@]: -7:0}
1      
1 
1      Substring expansion applied to an associative array produces
1      undefined results.
1 
1      Substring indexing is zero-based unless the positional parameters
1      are used, in which case the indexing starts at 1 by default.  If
1      OFFSET is 0, and the positional parameters are used, '$@' is
1      prefixed to the list.
1 
1 '${!PREFIX*}'
1 '${!PREFIX@}'
1      Expands to the names of variables whose names begin with PREFIX,
1      separated by the first character of the 'IFS' special variable.
1      When '@' is used and the expansion appears within double quotes,
1      each variable name expands to a separate word.
1 
1 '${!NAME[@]}'
1 '${!NAME[*]}'
1      If NAME is an array variable, expands to the list of array indices
1      (keys) assigned in NAME.  If NAME is not an array, expands to 0 if
1      NAME is set and null otherwise.  When '@' is used and the expansion
1      appears within double quotes, each key expands to a separate word.
1 
1 '${#PARAMETER}'
1      The length in characters of the expanded value of PARAMETER is
1      substituted.  If PARAMETER is '*' or '@', the value substituted is
1      the number of positional parameters.  If PARAMETER is an array name
1      subscripted by '*' or '@', the value substituted is the number of
1      elements in the array.  If PARAMETER is an indexed array name
1      subscripted by a negative number, that number is interpreted as
1      relative to one greater than the maximum index of PARAMETER, so
1      negative indices count back from the end of the array, and an index
1      of -1 references the last element.
1 
1 '${PARAMETER#WORD}'
1 '${PARAMETER##WORD}'
1      The WORD is expanded to produce a pattern just as in filename
1      expansion (⇒Filename Expansion).  If the pattern matches the
1      beginning of the expanded value of PARAMETER, then the result of
1      the expansion is the expanded value of PARAMETER with the shortest
1      matching pattern (the '#' case) or the longest matching pattern
1      (the '##' case) deleted.  If PARAMETER is '@' or '*', the pattern
1      removal operation is applied to each positional parameter in turn,
1      and the expansion is the resultant list.  If PARAMETER is an array
1      variable subscripted with '@' or '*', the pattern removal operation
1      is applied to each member of the array in turn, and the expansion
1      is the resultant list.
1 
1 '${PARAMETER%WORD}'
1 '${PARAMETER%%WORD}'
1      The WORD is expanded to produce a pattern just as in filename
1      expansion.  If the pattern matches a trailing portion of the
1      expanded value of PARAMETER, then the result of the expansion is
1      the value of PARAMETER with the shortest matching pattern (the '%'
1      case) or the longest matching pattern (the '%%' case) deleted.  If
1      PARAMETER is '@' or '*', the pattern removal operation is applied
1      to each positional parameter in turn, and the expansion is the
1      resultant list.  If PARAMETER is an array variable subscripted with
1      '@' or '*', the pattern removal operation is applied to each member
1      of the array in turn, and the expansion is the resultant list.
1 
1 '${PARAMETER/PATTERN/STRING}'
1 
1      The PATTERN is expanded to produce a pattern just as in filename
1      expansion.  PARAMETER is expanded and the longest match of PATTERN
1      against its value is replaced with STRING.  If PATTERN begins with
1      '/', all matches of PATTERN are replaced with STRING.  Normally
1      only the first match is replaced.  If PATTERN begins with '#', it
1      must match at the beginning of the expanded value of PARAMETER.  If
1      PATTERN begins with '%', it must match at the end of the expanded
1      value of PARAMETER.  If STRING is null, matches of PATTERN are
1      deleted and the '/' following PATTERN may be omitted.  If the
11      'nocasematch' shell option (see the description of 'shopt' in ⇒
      The Shopt Builtin) is enabled, the match is performed without
1      regard to the case of alphabetic characters.  If PARAMETER is '@'
1      or '*', the substitution operation is applied to each positional
1      parameter in turn, and the expansion is the resultant list.  If
1      PARAMETER is an array variable subscripted with '@' or '*', the
1      substitution operation is applied to each member of the array in
1      turn, and the expansion is the resultant list.
1 
1 '${PARAMETER^PATTERN}'
1 '${PARAMETER^^PATTERN}'
1 '${PARAMETER,PATTERN}'
1 '${PARAMETER,,PATTERN}'
1      This expansion modifies the case of alphabetic characters in
1      PARAMETER.  The PATTERN is expanded to produce a pattern just as in
1      filename expansion.  Each character in the expanded value of
1      PARAMETER is tested against PATTERN, and, if it matches the
1      pattern, its case is converted.  The pattern should not attempt to
1      match more than one character.  The '^' operator converts lowercase
1      letters matching PATTERN to uppercase; the ',' operator converts
1      matching uppercase letters to lowercase.  The '^^' and ',,'
1      expansions convert each matched character in the expanded value;
1      the '^' and ',' expansions match and convert only the first
1      character in the expanded value.  If PATTERN is omitted, it is
1      treated like a '?', which matches every character.  If PARAMETER is
1      '@' or '*', the case modification operation is applied to each
1      positional parameter in turn, and the expansion is the resultant
1      list.  If PARAMETER is an array variable subscripted with '@' or
1      '*', the case modification operation is applied to each member of
1      the array in turn, and the expansion is the resultant list.
1 
1 '${PARAMETER@OPERATOR}'
1      The expansion is either a transformation of the value of PARAMETER
1      or information about PARAMETER itself, depending on the value of
1      OPERATOR.  Each OPERATOR is a single letter:
1 
1      'Q'
1           The expansion is a string that is the value of PARAMETER
1           quoted in a format that can be reused as input.
1      'E'
1           The expansion is a string that is the value of PARAMETER with
1           backslash escape sequences expanded as with the '$'...''
1           quoting mechansim.
1      'P'
1           The expansion is a string that is the result of expanding the
11           value of PARAMETER as if it were a prompt string (⇒
           Controlling the Prompt).
1      'A'
1           The expansion is a string in the form of an assignment
1           statement or 'declare' command that, if evaluated, will
1           recreate PARAMETER with its attributes and value.
1      'a'
1           The expansion is a string consisting of flag values
1           representing PARAMETER's attributes.
1 
1      If PARAMETER is '@' or '*', the operation is applied to each
1      positional parameter in turn, and the expansion is the resultant
1      list.  If PARAMETER is an array variable subscripted with '@' or
1      '*', the operation is applied to each member of the array in turn,
1      and the expansion is the resultant list.
1 
1      The result of the expansion is subject to word splitting and
1      pathname expansion as described below.
1