Another bash array primer
I imagine most people who have tried more than once to use arrays in bash
have written up some syntax notes to refer back to when they inevitably forget
how to use them. These are mine.
Tip
|
Find the Arrays section in the bash man page by searching for
^\s{3}Arrays . That is, the start of the line, followed by 3 spaces,
followed by "Arrays". This assumes less or similar is your man pager,
|
Creating arrays
declare -a MY_ARRAY
-
Declare an empty global indexed array (zero-based).
declare -A MY_ARRAY
-
Declare an empty global associative array.
You do not need to declare indexed arrays before use. You do need to declare associative arrays before use. You can still assign to an undeclared "associative" array without error but it is actually an indexed array and all your string keys will be intepreted as index zero.
You can use local
instead of declare
to create local arrays within
functions using the same -a
and -A
options. However, if you use declare
inside a function, it will create a locally-scoped array anyway, unless you
use the -g
option (declare in global scope).
If you do not declare
an indexed array inside a
function and just create it by assigning a value, it will be a global
array, same as if you assign to a non-array variable inside a function
without using local
.
# Set value at index MY_ARRAY[0]="first" # Get value at index 0 echo ${MY_ARRAY[0]} > first # Get the length of the value at index 0 (number of characters) echo ${#MY_ARRAY[0]} > 5 # Set mapped value using "key" string declare -A MY_ARRAY MY_ARRAY[key]="value" # Get value at key echo ${MY_ARRAY[key]} > value # Create indexed array with initial values, indices assigned from 0 MY_ARRAY=(aaa bbb ccc) # Create indexed array with initial values, specify indices MY_ARRAY=([0]=aaa [2]=ccc [3]=ddd) # Create associative array with initial values using [key]=value format declare -A MY_ARRAY MY_ARRAY=([key1]=value1 [key2]=value2 [key3]=value3) # Create associative array with initial values using alternating keys and # values declare -A MY_ARRAY MY_ARRAY=(key1 value1 key2 value2 key3 value3) # Create _and_ do initial assignment to associative array declare -A MY_ARRAY=(key1 value1 key2 value2 key3 value3)
For associative arrays, you do not need to quote the key string between the square brackets, which act as double quotes.
Array size, index and value lists
Use a subscript of @
or *
to list all elements of the array. The choice
of which to use only matters if used within double quotes.
MY_ARRAY=(aaa bbb ccc) # Get the array size echo ${#MY_ARRAY[@]} > 3 # Get the array values as a list echo ${MY_ARRAY[@]} > aaa bbb ccc # Get the array subscripts (indices or keys) as a list echo ${!MY_ARRAY[@]} > 0 1 2
-
For an indexed array, the subscript list (indices) will be sorted.
-
For an associative array, the subscript list (keys) is not guaranteed to be sorted or in order of assignment.
-
The order of the value list and the subscript list will be the same. That is, the first value in the value list corresponds to the first subscript in the subscript list, and so on.
Negative indices
For indexed arrays, negative indices count back from the end of the array so -1 references the last element, -2 the second last element, and so on.
# Get the last element MY_ARRAY=(aaa bbb ccc) echo ${MY_ARRAY[-1]} > ccc
You can replace existing values using negative indices.
# Replace the last element MY_ARRAY=(aaa bbb ccc) MY_ARRAY[-1]='ddd' echo ${MY_ARRAY[@]} > aaa bbb ddd
Deleting
To delete an array or its elements, use unset
.
-
Delete an entire array:
unset MY_ARRAY
-
Delete an element of an array:
unset MY_ARRAY[0]
-
For an indexed array, unsetting an index will leave a gap in the index sequence.
MY_ARRAY=(aaa bbb ccc) # Array length echo ${#MY_ARRAY[@]} > 3 # Delete 2nd element unset MY_ARRAY[1] # List values echo ${MY_ARRAY[@]} > aaa ccc # List indices echo ${!MY_ARRAY[@]} > 0 2 # Array length after delete echo ${#MY_ARRAY[@]} > 2
Read input into an array
read -a
-
Read a line of text into an array, each word is an array element.
mapfile
orreadarray
-
Read all lines from a file into an array, each line is an array element.
When reading lines with read -a
, words are separated according to the IFS
value, which defaults to whitespace.
while read -a MY_ARRAY; do echo ${MY_ARRAY[@]} done < my_data.txt
When reading a file with mapfile
or readarray
(same thing), there are
various options to limit number of lines read, skip lines from start, use an
alternate delimiter, etc. See help mapfile
for info.
mapfile MY_LINES < my_data.txt
You cannot create an associative array using read
, mapfile
or readarray
,
only an indexed array.