GNU Info

Info Node: (zsh.info)Array Parameters

(zsh.info)Array Parameters


Next: Positional Parameters Up: Parameters
Enter node , (file) or (file)node

Array Parameters
================

To assign an array value, write one of:

     set -A NAME VALUE ...

     NAME=(VALUE ...)

If no parameter NAME exists, an ordinary array parameter is created.
If the parameter NAME exists and is a scalar, it is replaced by a new
array.  Ordinary array parameters may also be explicitly declared with:

     typeset -a NAME

Associative arrays _must_ be declared before assignment, by using:

     typeset -A NAME

When NAME refers to an associative array, the list in an assignment is
interpreted as alternating keys and values:

     set -A NAME KEY VALUE ...

     NAME=(KEY VALUE ...)

Every KEY must have a VALUE in this case.  Note that this assigns to
the entire array, deleting any elements that do not appear in the list.

To create an empty array (including associative arrays), use one of:

     set -A NAME

     NAME=()

Array Subscripts
----------------

Individual elements of an array may be selected using a subscript.  A
subscript of the form `[EXP]' selects the single element EXP, where EXP
is an arithmetic expression which will be subject to arithmetic
expansion as if it were surrounded by `$((...))'.  The elements are
numbered beginning with 1, unless the KSH_ARRAYS option is set in which
case they are numbered from zero.

Subscripts may be used inside braces used to delimit a parameter name,
thus `${foo[2]}' is equivalent to `$foo[2]'.  If the KSH_ARRAYS option
is set, the braced form is the only one that works, as bracketed
expressions otherwise are not treated as subscripts.

The same subscripting syntax is used for associative arrays, except that
no arithmetic expansion is applied to EXP.  However, the parsing rules
for arithmetic expressions still apply, which affects the way that
certain special characters must be protected from interpretation.  See
_Subscript Parsing_ below for details.

A subscript of the form `[*]' or `[@]' evaluates to all elements of an
array; there is no difference between the two except when they appear
within double quotes.  `"$foo[*]"' evaluates to `"$foo[1] $foo[2]
..."', whereas `"$foo[@]"' evaluates to `"$foo[1]" "$foo[2]" ...'.  For
associative arrays, `[*]' or `[@]' evaluate to all the values (not the
keys, but see _Subscript Flags_ below), in no particular order.  When
an array parameter is referenced as `$NAME' (with no subscript) it
evaluates to `$NAME[*]', unless the KSH_ARRAYS option is set in which
case it evaluates to `${NAME[0]}' (for an associative array, this means
the value of the key `0', which may not exist even if there are values
for other keys).

A subscript of the form `[EXP1,EXP2]' selects all elements in the range
EXP1 to EXP2, inclusive. (Associative arrays are unordered, and so do
not support ranges.) If one of the subscripts evaluates to a negative
number, say -N, then the Nth element from the end of the array is used.
Thus `$foo[-3]' is the third element from the end of the array foo, and
`$foo[1,-1]' is the same as `$foo[*]'.

Subscripting may also be performed on non-array values, in which case
the subscripts specify a substring to be extracted.  For example, if
FOO is set to `foobar', then `echo $FOO[2,5]' prints `ooba'.

Array Element Assignment
------------------------

A subscript may be used on the left side of an assignment like so:

     NAME[EXP]=VALUE

In this form of assignment the element or range specified by EXP is
replaced by the expression on the right side.  An array (but not an
associative array) may be created by assignment to a range or element.
Arrays do not nest, so assigning a parenthesized list of values to an
element or range changes the number of elements in the array, shifting
the other elements to accommodate the new values.  (This is not
supported for associative arrays.)

This syntax also works as an argument to the typeset command:

     typeset "NAME[EXP]"=VALUE

The VALUE may _not_ be a parenthesized list in this case; only
single-element assignments may be made with typeset.  Note that quotes
are necessary in this case to prevent the brackets from being
interpreted as filename generation operators.  The noglob precommand
modifier could be used instead.

To delete an element of an ordinary array, assign `()' to that element.
To delete an element of an associative array, use the unset command:

     unset "NAME[EXP]"

Subscript Flags
---------------

If the opening bracket, or the comma in a range, in any subscript
expression is directly followed by an opening parenthesis, the string up
to the matching closing one is considered to be a list of flags, as in
`NAME[(FLAGS)EXP]'.  The flags currently understood are:

w
     If the parameter subscripted is a scalar than this flag makes
     subscripting work on words instead of characters.  The default word
     separator is whitespace.

s:STRING:
     This gives the STRING that separates words (for use with the w
     flag).

p
     Recognize the same escape sequences as the print builtin in the
     string argument of a subsequent `s' flag.

f
     If the parameter subscripted is a scalar than this flag makes
     subscripting work on lines instead of characters, i.e. with
     elements separated by newlines.  This is a shorthand for `pws:\n:'.

r
     Reverse subscripting: if this flag is given, the EXP is taken as a
     pattern and the result is the first matching array element,
     substring or word (if the parameter is an array, if it is a
     scalar, or if it is a scalar and the `w' flag is given,
     respectively).  The subscript used is the number of the matching
     element, so that pairs of subscripts such as `$foo[(r)??,3]' and
     `$foo[(r)??,(r)f*]' are possible.  If the parameter is an
     associative array, only the value part of each pair is compared to
     the pattern, and the result is that value.  Reverse subscripts may
     be used for assigning to ordinary array elements, but not for
     assigning to associative arrays.

R
     Like `r', but gives the last match.  For associative arrays, gives
     all possible matches.

i
     Like `r', but gives the index of the match instead; this may not be
     combined with a second argument.  On the left side of an
     assignment, behaves like `r'.  For associative arrays, the key
     part of each pair is compared to the pattern, and the first
     matching key found is the result.

I
     Like `i', but gives the index of the last match, or all possible
     matching keys in an associative array.

k
     If used in a subscript on an associative array, this flag causes
     the keys to be interpreted as patterns, and returns the value for
     the first key found where EXP is matched by the key.  This flag
     does not work on the left side of an assignment to an associative
     array element.  If used on another type of parameter, this behaves
     like `r'.

K
     On an associative array this is like `k' but returns all values
     where EXP is matched by the keys.  On other types of parameters
     this has the same effect as `R'.

n:EXPR:
     If combined with `r', `R', `i' or `I', makes them give the Nth or
     Nth last match (if EXPR evaluates to N).  This flag is ignored
     when the array is associative.

b:EXPR:
     If combined with `r', `R', `i' or `I', makes them begin at the Nth
     or Nth last element, word, or character (if EXPR evaluates to N).
     This flag is ignored when the array is associative.

e
     This flag has no effect and for ordinary arrays is retained for
     backward compatibility only.  For associative arrays, this flag
     can be used to force * or @ to be interpreted as a single key
     rather than as a reference to all values.  This flag may be used
     on the left side of an assignment.

See _Parameter Expansion Flags_ (Note: Parameter Expansion) for
additional ways to manipulate the results of array subscripting.

Subscript Parsing
-----------------

This discussion applies mainly to associative array key strings and to
patterns used for reverse subscripting (the `r', `R', `i', etc. flags),
but it may also affect parameter substitutions that appear as part of
an arithmetic expression in an ordinary subscript.

The basic rule to remember when writing a subscript expression is that
all text between the opening `[' and the closing `]' is interpreted _as
if_ it were in double quotes (Note: Quoting).  However, unlike double
quotes which normally cannot nest, subscript expressions may appear
inside double-quoted strings or inside other subscript expressions (or
both!), so the rules have two important differences.

The first difference is that brackets (`[' and `]') must appear as
balanced pairs in a subscript expression unless they are preceded by a
backslash (`\').  Therefore, within a subscript expression (and unlike
true double-quoting) the sequence `\[' becomes `[', and similarly `\]'
becomes `]'.  This applies even in cases where a backslash is not
normally required; for example, the pattern `[^[]' (to match any
character other than an open bracket) should be written `[^\[]' in a
reverse-subscript pattern.  However, note that `\[^\[\]' and even
`\[^[]' mean the _same_ thing, because backslashes are always stripped
when they appear before brackets!

The same rule applies to parentheses (`(' and `)') and braces (`{' and
`}'): they must appear either in balanced pairs or preceded by a
backslash, and backslashes that protect parentheses or braces are
removed during parsing.  This is because parameter expansions may be
surrounded balanced braces, and subscript flags are introduced by
balanced parenthesis.

The second difference is that a double-quote (`"') may appear as part
of a subscript expression without being preceded by a backslash, and
therefore that the two characters `\"' remain as two characters in the
subscript (in true double-quoting, `\"' becomes `"').  However, because
of the standard shell quoting rules, any double-quotes that appear must
occur in balanced pairs unless preceded by a backslash.  This makes it
more difficult to write a subscript expression that contains an odd
number of double-quote characters, but the reason for this difference is
so that when a subscript expression appears inside true double-quotes,
one can still write `\"' (rather than `\\\"') for `"'.

To use an odd number of double quotes as a key in an assignment, use the
typeset builtin and an enclosing pair of double quotes; to refer to the
value of that key, again use double quotes:

     typeset -A aa
     typeset "aa[one\"two\"three\"quotes]"=QQQ
     print "$aa[one\"two\"three\"quotes]"

It is important to note that the quoting rules do not change when a
parameter expansion with a subscript is nested inside another subscript
expression.  That is, it is not necessary to use additional backslashes
within the inner subscript expression; they are removed only once, from
the innermost subscript outwards.  Parameters are also expanded from the
innermost subscript first, as each expansion is encountered left to
right in the outer expression.

A further complication arises from a way in which subscript parsing is
_not_ different from double quote parsing.  As in true double-quoting,
the sequences `\*', and `\@' remain as two characters when they appear
in a subscript expression.  To use a literal `*' or `@' as an
associative array key, the `e' flag must be used:

     typeset -A aa
     aa[(e)*]=star
     print $aa[(e)*]

A last detail must be considered when reverse subscripting is performed.
Parameters appearing in the subscript expression are first expanded and
then the complete expression is interpreted as a pattern.  This has two
effects: first, parameters behave as if GLOB_SUBST were on (and it
cannot be turned off); second, backslashes are interpreted twice, once
when parsing the array subscript and again when parsing the pattern.
In a reverse subscript, it's necessary to use _four_ backslashes to
cause a single backslash to match literally in the pattern.  For
complex patterns, it is often easiest to assign the desired pattern to
a parameter and then refer to that parameter in the subscript, because
then the backslashes, brackets, parentheses, etc., are seen only when
the complete expression is converted to a pattern.  To match the value
of a parameter literally in a reverse subscript, rather than as a
pattern, use `${(q)NAME}' (Note: Parameter Expansion) to quote the
expanded value.

Note that the `k' and `K' flags are reverse subscripting for an
ordinary array, but are _not_ reverse subscripting for an associative
array!  (For an associative array, the keys in the array itself are
interpreted as patterns by those flags; the subscript is a plain string
in that case.)

One final note, not directly related to subscripting: the numeric names
of positional parameters (Note: Positional Parameters) are parsed
specially, so for example `$2foo' is equivalent to `${2}foo'.
Therefore, to use subscript syntax to extract a substring from a
positional parameter, the expansion must be surrounded by braces; for
example, `${2[3,5]}' evaluates to the third through fifth characters of
the second positional parameter, but `$2[3,5]' is the entire second
parameter concatenated with the filename generation pattern `[3,5]'.


automatically generated by info2www version 1.2.2.9