Differences between revisions 6 and 8 (spanning 2 versions)
Revision 6 as of 2008-04-14 15:52:29
Size: 3030
Editor: 82-71-12-170
Comment:
Revision 8 as of 2008-09-09 13:52:20
Size: 4130
Editor: GreyCat
Comment: appending, and printing
Deletions are marked like this. Additions are marked like this.
Line 4: Line 4:
BASH and KornShell already have one-dimensional arrays indexed by a numerical expression, e.g. BASH and KornShell have one-dimensional arrays indexed by a numerical expression, e.g.
Line 7: Line 7:
 # Bash
Line 11: Line 12:
 while (($i < ${#host[@]} ))  while (( $i < ${#host[@]} ))
Line 18: Line 19:
The awkward expression {{{ ${#host[@]} }}} returns the number of elements for the array {{{host}}}. Also noteworthy is the fact that inside the square brackets, {{{i++}}} works as a C programmer would expect. The square brackets in an array reference force an ArithmeticExpression. The awkward expression `${#host[@]}` returns the number of elements for the array {{{host}}}. Also noteworthy for BASH is the fact that inside the square brackets, {{{i++}}} works as a C programmer would expect. The square brackets in an array reference force an ArithmeticExpression.  (That shortcut does not work in ksh88.)
Line 20: Line 21:
It's possible to assign multiple values to an array at once, but the syntax differs from Bash to KornShell: It's possible to assign multiple values to an array at once, but the syntax differs across shells.
Line 26: Line 27:
 # KornShell  # Korn
Line 32: Line 33:
 # Bash
Line 37: Line 39:
 # Korn/Bash
Line 43: Line 46:
If one simply wants to dump the full array, {{{"${arr[*]}"}}} will cause the elements to be concatenated together, with the first character of {{{IFS}}} (a space by default) between them. As it happens, "$*" is expanded the same way for positional parameters. If one simply wants to dump the full array, one element per line, this is the simplest approach:
Line 46: Line 49:
 # Bash/ksh
 printf "%s\n" "${arr[@]}"}}}

For more complex array-dumping, {{{"${arr[*]}"}}} will cause the elements to be concatenated together, with the first character of {{{IFS}}} (or a space if IFS isn't set) between them. As it happens, {{{"$*"}}} is expanded the same way for positional parameters.

 {{{
 # Bash
Line 50: Line 60:
BASH's arrays are also ''sparse''. Elements may be added and deleted out of sequence. BASH and Korn shell arrays are also ''sparse''. Elements may be added and deleted out of sequence.
Line 53: Line 63:
 # Bash
Line 62: Line 73:
 # Bash 3.0 or higher
Line 65: Line 77:
[:BashFAQ#faq73:Parameter Expansions] may be performed on array elements ''en masse'' as well: Bash's [:BashFAQ/073:Parameter Expansions] may be performed on array elements ''en masse'' as well:
Line 68: Line 80:
 # Bash
Line 75: Line 88:
 # Bash
Line 82: Line 96:
For examples of loading data into arrays, see [:BashFAQ#faq1:FAQ #1]. For examples of using arrays to hold complex shell commands, see [:BashFAQ#faq50:FAQ #50] and [:BashFAQ#faq40:FAQ #40]. If you wish to append data to an existing array, there are several approaches. The most flexible is to keep a separate index variable:

 {{{
 # Bash/ksh93
 arr[i++]="new item"}}}

If you don't want to keep an index variable, but you happen to know that your array is ''not sparse'', then you can use the highest existing index:

 {{{
 # Bash/ksh
 # This will FAIL if the array has holes (is sparse).
 arr[${#arr[*]}]="new item"}}}

If you don't know whether your array is sparse or not, but you don't mind re-indexing the entire array (and also being very slow), then you can use:

 {{{
 # Bash
 arr=("${arr[@]}" "new item")

 # Ksh
 set -A arr -- "${arr[@]}" "new item"}}}

If you're in bash 3.1 or higher, then you can use the {{{+=}}} operator:

 {{{
 # Bash 3.1
 arr+=("new item")}}}

For examples of loading data into arrays, see [:BashFAQ/001:FAQ #1]. For examples of using arrays to hold complex shell commands, see [:BashFAQ/050:FAQ #50] and [:BashFAQ/040:FAQ #40].

Anchor(faq5)

How can I use array variables?

BASH and KornShell have one-dimensional arrays indexed by a numerical expression, e.g.

  •  # Bash
     host[0]="micky"
     host[1]="minnie"
     host[2]="goofy"
     i=0
     while (( $i < ${#host[@]} ))
     do
         echo "host number $i is ${host[i++]}"
     done

The indexing always begins with 0.

The awkward expression ${#host[@]} returns the number of elements for the array host. Also noteworthy for BASH is the fact that inside the square brackets, i++ works as a C programmer would expect. The square brackets in an array reference force an ArithmeticExpression. (That shortcut does not work in ksh88.)

It's possible to assign multiple values to an array at once, but the syntax differs across shells.

  •  # Bash
     array=(one two three four)
    
     # Korn
     set -A array -- one two three four

Bash also lets you initialize an array using a [:glob:]:

  •  # Bash
     oggs=(*.ogg)

Using array elements en masse is one of the key features. In exactly the same way that "$@" is expanded for positional parameters, "${arr[@]}" is expanded to a list of words, one array element per word. For example,

  •  # Korn/Bash
     for x in "${arr[@]}"; do
       echo "next element is '$x'"
     done

This works even if the elements contain whitespace. You always end up with the same number of words as you have array elements.

If one simply wants to dump the full array, one element per line, this is the simplest approach:

  •  # Bash/ksh
     printf "%s\n" "${arr[@]}"

For more complex array-dumping, "${arr[*]}" will cause the elements to be concatenated together, with the first character of IFS (or a space if IFS isn't set) between them. As it happens, "$*" is expanded the same way for positional parameters.

  •  # Bash
     arr=(x y z)
     IFS=/; echo "${arr[*]}"; unset IFS
     # prints x/y/z

BASH and Korn shell arrays are also sparse. Elements may be added and deleted out of sequence.

  •  # Bash
     arr=(0 1 2 3)
     arr[42]="what was the question?"
     unset arr[2]
     echo "${arr[*]}"
     # prints 0 1 3 what was the question?

BASH 3.0 added the ability to retrieve the list of index values in an array, rather than just iterating over the elements:

  •  # Bash 3.0 or higher
     echo ${!arr[*]}
     # using the previous array, prints 0 1 3 42

Bash's [:BashFAQ/073:Parameter Expansions] may be performed on array elements en masse as well:

  •  # Bash
     arr=(abc def ghi jkl)
     echo "${arr[@]#?}"          # prints bc ef hi kl
     echo "${arr[@]/[aeiou]/}"   # prints bc df gh jkl

Parameter Expansion can also be used to extract elements from an array:

  •  # Bash
     echo "${arr[@]:1:3}"        # three elements starting at #1 (second element)
     echo "${arr[@]:(-2)}"       # last two elements
     echo "${@:(-1)}"            # last positional parameter
     echo "${@:(-2):1}"          # second-to-last positional parameter

The @ array (the array of positional parameters) can be used just like any regularly named array.

If you wish to append data to an existing array, there are several approaches. The most flexible is to keep a separate index variable:

  •  # Bash/ksh93
     arr[i++]="new item"

If you don't want to keep an index variable, but you happen to know that your array is not sparse, then you can use the highest existing index:

  •  # Bash/ksh
     # This will FAIL if the array has holes (is sparse).
     arr[${#arr[*]}]="new item"

If you don't know whether your array is sparse or not, but you don't mind re-indexing the entire array (and also being very slow), then you can use:

  •  # Bash
     arr=("${arr[@]}" "new item")
    
     # Ksh
     set -A arr -- "${arr[@]}" "new item"

If you're in bash 3.1 or higher, then you can use the += operator:

  •  # Bash 3.1
     arr+=("new item")

For examples of loading data into arrays, see [:BashFAQ/001:FAQ #1]. For examples of using arrays to hold complex shell commands, see [:BashFAQ/050:FAQ #50] and [:BashFAQ/040:FAQ #40].

BashFAQ/005 (last edited 2023-03-25 22:39:06 by emanuele6)