Arrays can be used to store a bunch of values or elements. This way we can reference multiple items by a single name (i.e name of array). In this post let us look at some common examples using Arrays, which we might need to refer to, in our day to day scripting tasks.

Create and print Array elements

Create an array ‘x’ and print all of its elements.

$ x=('1' 'a' 'tt' 'y')
$ echo ${x[@]}

1 a tt y

print the 3rd element in array variable x.

$ x=('1' 'a' 'tt' 'y')
$ echo ${x[2]}

tt

Print array except for an element in it

print all but element ‘y’ from the array.

$ x=('1' 'a' 'tt' 'y')
$ echo ${x[@]/y}

1 a tt

Remove an element from an array

delete element ‘y’ from array x

$ x=('1' 'a' 'tt' 'y')
$ x=( "${x[@]/y}" )
$ echo ${x[@]}

1 a tt

Note that element ‘y’ has been removed from array variable x.

Remove multiple elements from an array

In the below example, we delete any element of array ‘x’ if it is also found in array ‘del’. We use a ‘for’ loop to iterate through array ‘del’ and check if each of its elements is also found in array ‘x’ and we delete the element if found.

x=('1' 'a' 'tt' 'y')
del=('1' 'tt')
for i in ${del[@]}
do
   x=("${x[@]/$i}") 
done
echo ${x[@]}

a y

Note that ‘1’ and ‘tt’ has been deleted from array ‘x’.

The above method work well when the elements are unique. If the elements have common sub-strings same as the search string, then they also get removed.
example:

$ x=('1' 'a' 'ay')
$ del=('a')
$ for i in ${del[@]}; do x=("${x[@]/$i}"); done
$ echo ${x[@]}

1 y

Note that since ‘a’ is a substring of ‘ay’, it has been removed and left with only ‘y’

1 – Using unset

Using unset is one way to handle this problem.

$ array=(one two three onea)
$ del=(one)
$ echo BEFORE unset: echo ${array[@]}

BEFORE unset: one two three onea

$ unset 'array[$del]'
$ echo AFTER unset: ${array[@]}

AFTER unset: two three onea

We see that sub-strings are ignored from deletion. Note that substring ‘one’ of string ‘onea’ did not get deleted, however the individual string ‘one’ has been deleted.

Running ‘unset’ does not re-order index position, we reorder the index numbers, by doing the following.

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

2 – Using for loop

We can also use ‘for’ loop instead of ‘unset’ to handle the aforementioned problem. Each element is checked individually in a ‘for’ loop and deleted if it matches.

#!/bin/bash
ARRAY=(one two onetwo three four threefour)
echo BEFORE: ${ARRAY[@]}
TO_REMOVE=(one four)
echo TO REMOVE: ${TO_REMOVE[@]}
TEMP_ARRAY=()
for i in "${ARRAY[@]}"; do
    for remove in "${TO_REMOVE[@]}"; do
        KEEP=true
        if [[ ${i} == ${remove} ]]; then
            KEEP=false
            break
        fi
    done
    if ${KEEP}; then
        TEMP_ARRAY+=(${i})
    fi
done
ARRAY=("${TEMP_ARRAY[@]}")
echo AFTER: ${ARRAY[@]}

BEFORE: one two onetwo three four threefour
TO REMOVE: one four
AFTER: two onetwo three threefour

Delete array element based on position

$ array=(one two three)
$ echo ${array[@]}

Array before deletion:

one two three

$ unset 'array[1]'
$ echo ${array[@]}

Array after deletion of element in position 2 i.e at index 1 (indexing starts at 0):

one three

Note that the second element has been removed.

Bash one liner to add element to array

printing array before adding element:

$ echo ${ARRAY[@]}

two onetwo three threefour one six

printing array after adding element ’11’:

$ ARRAY+=("eleven")
$ echo ${ARRAY[@]}

two onetwo three threefour one six eleven

Search and replace string in bash

$ Unix=('Debian' 'red hat' 'Ubuntu' 'Suse' 'Fedora')
$ echo ${Unix[@]/[rR]ed*/open BSD}

Debian open BSD Ubuntu Suse Fedora

Note that ‘red hat’ has been replaced with ‘open BSD’ in this example. [rR]ed* is a regular expression that denotes any string starting with ‘Red’ or ‘red’. Thus any string of this pattern should get replaced with ‘open BSD’.

Print the length of an array in bash

Printing the array element ‘Unix’.

$ echo ${Unix[@]}

Debian red hat Ubuntu Suse Fedora

Printing the length array element ‘Unix’ by prefixing ‘#’.

$ echo ${#Unix[@]}

5

Convert a string or text into an array delimited by a character

In this example we will split a single string “string1+string2+string3” with ‘+’ as delimiter and convert it into an array.

$ a="string1+string2+string3"
$ IFS='+' read -r -a array <<< "$a"
$ echo ${array[@]}

string1 string2 string3

Printing only the 0th element of array.

$ echo ${array[0]}

string1