How to use indexed arrays in bash

Last updated on April 4, 2021 by Dan Nanni

In programming languages, an array is a data structure that represents a collection of objects with the same data type. Although it's not a full-blown programming language, bash also supports array-type variables. Once declared as an array implicitly or explicitly, a given bash variable can store multiple values in it. Depending on how the values are accessed from the array, bash supports two types of arrays: associative arrays or one-dimensional indexed arrays. The former is often called key-value dictionaries or hash maps, where values are accessed by corresponding keys. The latter type of arrays are essentially ordered lists, where you can access the values by their index (i.e., position in the list).

We already covered associative arrays in another bash tutorial. Thus, in this post, let's focus on indexed arrays and find out how we can use this type of bash arrays. Various usages of indexed arrays will be illustrated with examples.

Declare an Indexed Array in Bash

While a given bash variable can be implicitly declared as an array by applying an array operation to it, you can explicitly declare a variable as an indexed array by using the built-in declare command with -a option. Note that -A option is used for associated arrays.

$ declare -a <variable-name>

Initialize an Indexed Array in Bash

You can initialize an indexed array in several ways. Since bash arrays can store either integers or strings, a given array variable can be initialized with an array of integers or an array of strings. You can even store a mix of integers and strings. However, you cannot create nested arrays such as an array of arrays. Bash only supports one-dimensional arrays.

# Initialize an indexed array while explicitly declaring it
declare -a my_array=(2 4 6 8 10)

# Implicitly declare an indexed array by initializing it
my_array2=(orange apple grape mango)

# Store a mix of integers and strings
my_array3=(100 200 "bob" 500 "dan")

If you want to initialize every element in a big array with a default value, you can use for-loop with brace expansion.

# Initailize an array of size 500 with the default value zero
declare -a my_big_array=( $(for i in {1..500}; do echo 0; done) )

Read and Write a Value in Indexed Array

To read or write a value at a specific index position in an indexed array, specify the index with square brackets. To read an element, you need additional curly brackets around the array name.

test_array[0]=foobar        # write
echo ${test_array[0]}       # read

If you do not initialize an array, each element in the array is initialized with an empty value by default. For example:

declare -a my_array
my_array[10]=apple

# Attempt to access an uninitialized element at index 0
if [ -z "${my_array[0]}" ]; then
    echo "The element at index 0 is empty"
else
    echo "The element at index 0 is non-empty: ${my_array[0]}"
fi

This script will produce the following output:

The element is empty

Find Array Length in Bash

When you want to find out the length of an indexed array, you can use the following expression with # and @ symbols.

fruit_array=(orange apple grape mango)
echo "Array size: ${#fruit_array[@]}"
Array size: 4

Append to Array in Bash

Instead of writing a value at a specific position of an array, you can dynamically append one or more values to the end of an array. Use the += operator to do that. There is no maximum size limit on bash arrays.

declare -a color_array=(red yellow)
color_array+=(blue)
color_array+=(black white)

Another way to grow an indexed array incrementally is the following.

fruit_array=(orange apple grape mango)
fruit_array=(${fruit_array[@]} pineappe watermelon)

You can also append a value to the end of an array by utilizing array length information. Basically you insert a value at the last index of an array.

fruit_array[${#fruit_array[@]}]=kiwi

Iterate an Array in a Loop

If you want to loop through an indexed array, you can use the following for loop.

declare -a color_array=(red yellow skyblue gray black white)

for color in ${color_array[@]}; do
    echo $color
done

Alternatively, you can iterate an array using array indices as follows. An advantage of using array indices is that you can flexibly stop the iteration based on index.

declare -a color_array=(red yellow skyblue gray black white)

for i in ${!color_array[@]}; do
    echo ${color_array[$i]}
done

Print an Indexed Array

If you want to print the content of an array, you can of course loop through the array, and print each value individually. Another more convenient way, especially when an array is small, is to use <array-name>[@], which returns the content of the array.

color_array=(red yellow skyblue gray black white)
echo ${color_array[@]}
red yellow skyblue gray black white

Slice an Array Based on Array Indices

Array slicing is useful when you want to retrieve a consecutive subset of values from an array based on their indices (e.g., values from index 3 to 6 of an array). Indexed arrays in bash support different types of array slicing as follows.

The entire array:

${my_array[@]}

Array slice of length <len>, starting from <index>:

${my_array[@]:index:len}

Array slice of length <len>, starting from index 0:

${my_array[@]::len}

Array slice starting from <index> to the end of an array:

${my_array[@]:index}

Check out the following bash array slicing examples to better understand its usage.

declare -a color_array=(red yellow skyblue gray black white pink purple)

# Retrieve the whole array
echo "Slice #1: ${color_array[@]}"

# Retrieve 2 values starting from index 3
echo "Slice #2: ${color_array[@]:3:2}"

# Retrieve the first 5 values
echo "Slice #3: ${color_array[@]::5}"

# Retrieve values starting from index 4 til the end
echo "Slice #4: ${color_array[@]:4}"
Slice #1: red yellow skyblue gray black white pink purple
Slice #2: gray black
Slice #3: red yellow skyblue gray black
Slice #4: black white pink purple

If you find this tutorial helpful, I recommend you check out the series of bash shell scripting tutorials provided by Xmodulo.

Support Xmodulo

This website is made possible by minimal ads and your gracious donation via PayPal (Credit Card) or Bitcoin (1M161JGAkz3oaHNvTiPFjNYkeABox8rb4g).

Please note that this article is published by Xmodulo.com under a Creative Commons Attribution-ShareAlike 3.0 Unported License. If you would like to use the whole or any part of this article, you need to cite this web page at Xmodulo.com as the original source.

Xmodulo © 2021 ‒ AboutWrite for Us ‒ Feed ‒ Powered by DigitalOcean