Data Structures

I used to say that once you find you need data structures it's time to move on to a complete scripting language, but bash nowadays actually does have arrays and hashes, and I consider it a challenge to make good use of them.

Arrays (indexed Arrays)

Initialization

Initialize with values:

thearray=("1 One" "2 Two" "3 Three" "4 Four")

Initialize an empty array:

declare -a thearray

Accessing values

Number of Values:

$ echo ${#thearray[*]}
4

First and last Value:

$ echo "${thearray[0]}"
1 One
$ echo "${thearray[-1]}"
4 Four

Iterating over all Values

Right:

$ for element in "${thearray[@]}"; do echo "${element}"; done
1 One
2 Two
3 Three
4 Four

Wrong:

$ for ELEMENT in ${thearray[@]}; do echo "${element}"; done
1
One
2
Two
3
Three
4
Four

Deleting or adding Values

Delete:

$ unset thearray[2]
$ for element in "${thearray[@]}"; do echo "${element}"; done
1 One
2 Two
4 Four
$ echo ${#thearray[*]}
3

Add:

$ thearray+=("5 Five")
$ for element in "${thearray[@]}"; do echo "${element}"; done
1 One
2 Two
4 Four
5 Five

Concatenate and Slice

Concatenate:

$ array2=("6 Six" "7 Seven")
$ thearray=("${thearray[@]}" "${array2[@]}")
$ for element in "${thearray[@]}"; do echo "${element}"; done
1 One
2 Two
4 Four
5 Five
6 Six
7 Seven

Slice:

$ thearray=("${thearray[@]:0:2}" "3 Three" "${thearray[@]:2:4}")

$ for element in "${thearray[@]}"; do echo "${element}"; done
1 One
2 Two
3 Three
4 Four
5 Five
6 Six
7 Seven

Hashes (Associative Arrays)

Initialization

declare is mandatory for hashes:

$ declare -A thehash
$ thehash=(["Month 1"]="January" ["Month 2"]="February")
$ thehash["Month 3"]="March"

Accessing Values

$ echo ${thehash["Month 1"]}
January

Iterating over all Values

$ for key in "${!thehash[@]}"; do printf "%s -> %s\n" "$key" "${thehash["$key"]}"; done
Month 2 -> February
Month 3 -> March
Month 1 -> January

Deleting Values

$ unset thehash["Month 3"]

Showing contents of an indexed or associative array

This uses parameter transformation to create a declare command that could be used to recreate the given data.

#!/usr/bin/env bash

declare -A thehash
thehash=(["Month 1"]="January" ["Month 2"]="February")
thearray=("1 One" "2 Two" "3 Three" "4 Four")

echo "${thehash[@]@A}"
echo "${thearray[@]@A}"