bash: Shell Parameter Expansion

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