Arrays
Any worthy programming language must support collections of things. The ubiquitous collection is the array, which usually is an ordered collection with fixed size that can contain duplicates.
From the source: GNU bash manual: Arrays.
Literally defining an array
Arrays are defined literally as follows:
myarray1=(a b "c d") myarray2=($(ls))
Note that:
- Forgetting the parentheses ( myarray1=a b "c d") will work just fine, but the result is not an array... This can make for some cryptic errors when you start using the "array".
- The third (and last!) element in myarray1 is the string "c d"- see quoting arguments.
- Each entry in myarray2 is the name of a file in the current directory.
A variable can optionally be explicitly defined as being of type array:
myarray=(1 2 3) declare -a myarray
This provides information for the bash interpreter and your fellow programmers that the variable is not intended to contain anything but an array - possibly combined with -r, making it a readonly array.
Iterating over an array
Execute a command for each element in an array:
myarray=(a b c) for file in "${myarray[@]}"; do command $file done
Bash is very flexible concerning how to perform this kind of loop. In the example above, ${myarray[@]} (same without quotes) and ${myarray[*]} would have had the same effect, but "${myarray[*]}" would consider the entire array contents as one element, see Joining array elements into a string.
Indexing an array
Access a specific element in an array:
myarray=(a b c) echo ${myarray[2]} # writes "c" on stdout
The first element in an array has index 0:
echo ${myarray[0]} # writes "a" to stdout
Indexing beyond the last element in an array simply yields the empty string:
echo x${myarray[37]}x # outputs 'xx'
Default Index
The default index is 0, which is often not what you want:
test "${myarray}" == "${myarray[0]}" # always evaluates to 0 (OK)
This also works for assignment:
> declare -a mya=(a b c) > echo "${mya[0]}" a > echo "${mya[@]}" a b c > mya=d > echo "${mya[0]}" d > echo "${mya[@]}" d b c
For clarity, always specify the index, even when you want the first element.
Length of an array
The somewhat cryptic syntax for the length of an array is excused by it's similarity to the syntax for finding the length of variables of simple types:
myarray=(1 2 3) echo ${#myarray[*]} # writes "3" to stdout echo ${#myarray[@]} # writes "3" to stdout
Joining array elements into a string
Join the contents of an array together into a string using "${myarray[*]}". When passed as an argument, this will be considered a single argument. Assume arg_count.sh is:
#!/bin/bash echo $#
The following illustrates the difference between "${myarray[*]}" and the other ways of accessing the contents of an array:
myarray=(1 2 3) ./arg_count.sh ${myarray[@]}; # writes 3 to stdout ./arg_count.sh ${myarray[*]}; # writes 3 to stdout ./arg_count.sh "${myarray[@]}"; # writes 3 to stdout ./arg_count.sh "${myarray[*]}"; # writes 1 to stdout
For the first three cases, the first argument to the script is 1, in the last case, it is 1 2 3.
Appending an element to the end of an array
When iteratively constructing an array, it is sometimes useful to append elements to the end:
# init myarray[0]=a # loop for element in b c d; do myarray[${#myarray[*]}]=${element} done
The array now contains (a b c d).
Note: This only works if there are no unassigned indexes in the array. This is usually the case when dynamically constructing an array as above, but it might not be true for any given array.