Bash Associative Arrays

An associative array stores data as key and value pairs. A normal array finds items by number, while an associative array finds items by a name. Think of a phone contact list: you search for "Asha" and the phone shows her number.

Normal Array Versus Associative Array

  Normal Array                 Associative Array
  +-------+----------+         +----------+----------+
  | Index | Value    |         | Key      | Value    |
  +-------+----------+         +----------+----------+
  |   0   | Apple    |         | name     | Asha     |
  |   1   | Banana   |         | city     | Pune     |
  |   2   | Mango    |         | role     | Tester   |
  +-------+----------+         +----------+----------+

Version Requirement

Associative arrays need Bash 4.0 or higher. Check the version before use:

bash --version

Old macOS machines with Bash 3.2 show an error. Install a newer Bash with Homebrew to fix it.

Declare an Associative Array

The declare -A command creates the array. The capital A matters.

declare -A person
person[name]="Asha"
person[city]="Pune"
person[role]="Tester"

Fill the Array in One Line

declare -A person=( [name]="Asha" [city]="Pune" [role]="Tester" )

Read a Value

Use curly braces and the key name:

echo "Name: ${person[name]}"
echo "City: ${person[city]}"

Output:

Name: Asha
City: Pune

List All Keys and All Values

echo "Keys: ${!person[@]}"
echo "Values: ${person[@]}"
echo "Total pairs: ${#person[@]}"

The exclamation mark before the name returns keys. The hash sign returns the count. Bash does not guarantee any key order in the output.

Loop Over Pairs

#!/bin/bash
declare -A marks=( [Maths]=88 [Science]=92 [English]=79 )

for subject in "${!marks[@]}"
do
  echo "$subject scored ${marks[$subject]}"
done

Output (order may differ):

Science scored 92
Maths scored 88
English scored 79

Update, Add, and Remove Pairs

marks[Maths]=95        # update an existing key
marks[History]=84      # add a new key
unset marks[English]   # remove a key

Check Whether a Key Exists

The test -v checks for a key without reading its value:

if [[ -v marks[Science] ]]; then
  echo "Science marks found"
else
  echo "Science marks missing"
fi

Practical Example: Count Word Frequency

Associative arrays count items well. This script counts how often each fruit appears.

#!/bin/bash
declare -A count

for fruit in apple mango apple banana mango apple
do
  (( count[$fruit]++ ))
done

for fruit in "${!count[@]}"
do
  echo "$fruit: ${count[$fruit]}"
done

Output:

apple: 3
mango: 2
banana: 1

Each pass adds one to the counter that belongs to that fruit. A missing key starts at zero automatically.

Practical Example: Country Codes Lookup

#!/bin/bash
declare -A code=( [India]="+91" [Japan]="+81" [Brazil]="+55" )

read -p "Enter country: " country

if [[ -v code[$country] ]]; then
  echo "Dialing code: ${code[$country]}"
else
  echo "Country not in the list"
fi

Keys With Spaces

Quote any key that holds spaces:

declare -A city_pin
city_pin["New Delhi"]="110001"
echo "${city_pin["New Delhi"]}"

Pass the Array Around

Functions cannot receive an associative array as a plain argument. Declare the array globally and let the function read it by name, or pass the keys as separate arguments.

Key Takeaways

  • An associative array maps a key to a value.
  • Declare it with declare -A before any use.
  • ${!array[@]} returns keys and ${array[@]} returns values.
  • Use -v inside [[ ]] to test for a key.
  • Bash 4.0 or higher is required.
  • Counting, lookup tables, and settings storage are the most common uses.