Arrays

Arrays, also known as index set of variables, is also available in BASH. Normally, arrays are used to store closely related variables together so that you can identify via an incremental index number.

Array is stored as one entity in a variable, followed by the square bracket([]) for you to index the value. We will look into Array via Create, Read, Update, and Delete (CRUD) mechanism. This allows us to fully understand how to apply and to manipulate arrays in BASH.

Create

There are 2 ways to create an array: one at a time or all at once. We will look into each of them.

One at a Time

You can quickly create an array element (with the array if it is not available) alongside with its index. Here is an example:

country[0]="United States of America"
country[1]=United\ Kingdom
country[2]=Canada
country[3]=Australia

This creates the array "country" where the first (0) is United States of America, second (1) is United Kingdom, and so on.


All at Once

You can also quickly create the full array all at once using the separate list. The downside however, is that you need to be very cautious with values containing spaces or special command characters. Here is an ideal practice (the last one being a variable for demonstration):

my_country="Australia"
country=('United States of America' 'United Kingdom' 'Canada' "$my_country")

Read

There are various ways to read values from an array, including the array itself.

Read Specific Element

To read a value of an element, simply provide the index to the array using the variable manipulation. Here is an example:

$ echo "${country[1]}"        #➔ United Kingdom

Read All Elements

To read all the values in one go, supply @ or * as index instead. If you use *, it will print all the values in one line joined by the $IFS separator if available.

$ echo "${country[@]}"                #➔ United States of America United Kingdom Canada Australia
$ IFS="|" && echo "${country[@]}"     #➔ United States of America United Kingdom Canada Australia
$ IFS="|" && echo "${country[*]}"     #➔ United States of America|United Kingdom|Canada|Australia


Read Length of Array

To find out the length of the array, use the variable string length checking functionality (# in front of variable name) across all elements. Here is an example:

$ echo "${#country[@]}"        #➔ 4

IMPORTANT NOTE:

  • You must supply all the elements([@]) to the length checker. Otherwise, it will only read the length of the first element.


Read Elements Through Looping

You can also read all elements one-by-one through looping. Here is a simple example:

for item in "${country[@]}"; do
        echo "$item"
done

If you want the index, you can make good use of the array key (the ! ) symbol:

for i in "${!country[@]}"; do
        echo "position $i is ${country[$i]}"
done

NOTE:

  1. If you see the index jumped (missing some numbers), the missing element got deleted without having the array re-indexed (See below for Delete An Element). Performing a re-index should get you the proper index numbers.
  2. Alternatively, on the safe side, you can simply supply a variable and increment alongside the loop. Here is an example:
i=0
for item in "${country[@]}"; do
        echo "position $i is $item"
        ((i++))
done
unset i


Read Selected Set of Elements

You can read a selected set of elements from a given index. This follows the string manipulation pattern like:

${variable[@]:<index>:<number of elements>}

So, here is an example:

  • at index 1, read 2 elements ➔ ${variable[@]:1:2}
  • at index 1, read 1 elements ➔ ${variable[@]:1:1}
  • at index 1, read all remaining elements (don't supply number of elements at all) ➔ ${variable[@]:1}

Based on the examples above, here are some examples for selective reading:

$ echo "${country[@]:2:4}"        #➔ Canada Australia
$ echo "${country[@]:2:3}"        #➔ Canada Australia
$ echo "${country[@]:2:2}"        #➔ Canada Australia
$ echo "${country[@]:2:1}"        #➔ Canada
$ echo "${country[@]:1:1}"        #➔ United Kingdom
$ echo "${country[@]:1:2}"        #➔ United Kingdom Canada
$ echo "${country[@]:1:3}"        #➔ United Kingdom Canada Australia
$ echo "${country[@]:1:4}"        #➔ United Kingdom Canada Australia
$ echo "${country[@]:1}"          #➔ United Kingdom Canada Australia

NOTE:

  1. If number of elements is overstated, the function will returns empty string for that element instead of raising an error.

Update

There is no strict method to update an array. However, these are the common encounters for updating an array.


Update Element's Value

To update a value, simply repeat the "Create - One at a Time" at your designated index. Example, updating 2 from Canada to Africa:

country[2]="Africa"


Add Element At the Front

To add a new element in the front, you basically rebuild the array using the "Create - all at once". Here is the pattern:

array=("new element" "${array[@]}")

Based on the example above:

country=("Malaysia" "${country[@]}")


Add Element At the Last

To add a new element in the end, you use the addition or the rebuild the array using the "Create - all at once" method. Here are the patterns:

array+=("new element")

#OR 

array=("${array[@]}" "new element")

Based on the example above:

country+=("Malaysia")

# OR

country=("${country[@]}" "Malaysia")


Add Element At A Given Index

To add a new element at a given index, you basically rebuild the array with the intended index. Here is the pattern:

array=("${array[@]:0:<index>}" "new_element" "${array[@]:<index>}")

Based on the example above:

index=1
country=("${country[@]:0:$index}" "Malaysia" "${country[@]:$index}")
unset index


Delete

You can perform delete operations for an array. These are the common encountering for such operations.


Delete an Element

Deleting an element is as simple as unset the element itself. However, BASH does not re-index the array for you. Hence, you will need to do the additional step is to re-index the array yourself. Here's the pattern:

$ unset array[<index>]
$ array=("${array[@]}")        # re-index step

Based on the example above:

$ unset country[2]
$ country=("${country[@]}")

IMPORTANT NOTE:

  • if you do not re-index the array (array=("${array[@]}")), the array key is not updated and will cause a confusion index identity for that particular array. Here's a case where we deleted the 3rd element without re-indexing; then performing the re-indexing:
$ for i in "${!country[@]}"; do echo "position $i is ${country[$i]}"; done
position 0 is Malaysia
position 1 is United States of America
position 2 is United Kingdom
position 3 is Africa
position 4 is Canada
position 5 is Australia
$ unset country[3]
$ for i in "${!country[@]}"; do echo "position $i is ${country[$i]}"; done
position 0 is Malaysia
position 1 is United States of America
position 2 is United Kingdom
position 4 is Canada
position 5 is Australia
$ country=("${country[@]}")
$ for i in "${!country[@]}"; do echo "position $i is ${country[$i]}"; done
position 0 is Malaysia
position 1 is United States of America
position 2 is United Kingdom
position 3 is Canada
position 4 is Australia


Delete the Array

To delete the entire array, simply unset the array variable. This will cause the entire array to disappear.

$ unset array

Based on the example above:

$ unset country


Associative Array / Maps / Dictionary

BASH does support associative array or in some other programming language, called it as "maps" or "dictionary". This also means that you can use a string label instead of numeric indexing. Here's an example:

country["US"]="United States of America"
country["MY"]="Malaysia"
country["UK"]="United Kingdom"

To use it, simply call it like a normal array:

$ echo "${country["MY"]}"        #➔ United Kingdom

The rest of the array operations applies similarly to the conventional array convention.

NOTE:

  • Depending on the array nature, if you mixed a associative index entry into a numeric index nature array, the first element of the array got deleted; chaos may happen if you mix it the other way round. Hence, don't mix associative index and numeric index up.
$ country=("United States of America" "United Kingdom")
$ country["MY"]="Malaysia"
$ for i in "${!country[@]}"; do echo "position $i is ${country[$i]}"; done
position 0 is Malaysia
position 1 is United Kingdom

That's all about BASH array. Feel free to organize your clustered variable together in your BASH script.