100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Bash

Associative Arrays

Bash 4+ associative arrays bring key-value maps to shell scripting — learn declaration, iteration order, key existence checks, and real-world patterns like counters and lookup tables.

Advanced FundamentalsAdvanced10 min readJul 10, 2026
Analogies

Declaring Associative Arrays

Unlike indexed arrays, associative arrays require explicit declaration with declare -A (or local -A inside a function) before any keys can be assigned, because Bash needs to know upfront that string keys, not integers, will be used; attempting to assign a string key to a plain array declared without -A silently coerces the key to 0 or fails, a common source of confusion. Once declared, keys are set with array[key]=value, using any string as a key, including ones with spaces if quoted.

🏏

Cricket analogy: Declaring declare -A before use is like registering a franchise's player-auction database with named categories (batsman, bowler, all-rounder) before the auction begins — without that upfront setup, the system has no way to file entries by name instead of just a numbered lot.

bash
#!/usr/bin/env bash
set -euo pipefail

declare -A capitals
capitals[France]="Paris"
capitals[Japan]="Tokyo"
capitals["South Korea"]="Seoul"   # quoted key with a space

# Bulk declaration
declare -A http_status=(
  [200]="OK"
  [404]="Not Found"
  [500]="Internal Server Error"
)

echo "${capitals[Japan]}"          # Tokyo
echo "${http_status[404]}"         # Not Found

Iteration, Key Existence, and Unordered-ness

Iterating over an associative array's keys uses "${!array[@]}" (the ! prefix requests the indices/keys rather than the values), and the corresponding values are retrieved inside the loop with ${array[$key]}; critically, Bash does not guarantee any particular iteration order for associative arrays, so scripts that need sorted or deterministic output must explicitly sort the keys first, typically by piping them through sort. Checking whether a key exists (as opposed to whether its value is non-empty) requires the -v test: [[ -v array[key] ]], since a key can legitimately exist with an empty string value.

🏏

Cricket analogy: Iterating "${!array[@]}" over a table of team-to-net-run-rate mappings without a guaranteed order is like a scoreboard listing teams in whatever order they were last updated rather than by league standing — you must explicitly sort by points to get the real table.

[[ -v array[key] ]] tests key existence regardless of value, while [[ -n "${array[key]}" ]] tests whether the value is non-empty. These are different questions: a key can be explicitly set to an empty string (array[foo]=""), in which case -v is true but -n is false. Use -v whenever you specifically need to distinguish 'key was never set' from 'key was set to an empty value'.

bash
declare -A word_count
text=(the quick brown fox the lazy fox the dog)

for word in "${text[@]}"; do
  word_count["$word"]=$(( ${word_count["$word"]:-0} + 1 ))
done

# Deterministic, sorted output
for word in $(printf '%s\n' "${!word_count[@]}" | sort); do
  echo "$word: ${word_count[$word]}"
done

# Key existence vs. non-empty value
word_count[empty_key]=""
[[ -v word_count[empty_key] ]] && echo "empty_key exists"
[[ -n "${word_count[empty_key]}" ]] || echo "but its value is empty"

Practical Patterns: Counters, Lookup Tables, and Sets

Associative arrays are the natural fit for frequency counters (as shown above), configuration lookup tables that map environment names to endpoints or credentials, and set-membership checks where you only care whether a key exists (array[value]=1 for every seen item, then test with -v). Because associative arrays cannot be nested in Bash the way they can in languages like Python or JavaScript, multi-dimensional data is typically flattened into composite keys, e.g. matrix["$row,$col"]=value, which works well but requires careful key-format discipline to avoid collisions.

🏏

Cricket analogy: A set-membership pattern like seen_batsmen[Kohli]=1 checking whether a player has already batted this innings mirrors an umpire's mental checklist of who has already had their turn, quickly answerable with a single existence check rather than scanning the whole scorecard.

Associative arrays require Bash 4.0 or later (declare -A is unavailable in Bash 3.2, which macOS shipped as the default /bin/bash for years due to licensing). If your script targets systems that might still have Bash 3.2 as the default (check with bash --version), either require users to install a newer Bash via Homebrew or restructure the logic to avoid associative arrays entirely.

  • Associative arrays must be explicitly declared with declare -A (or local -A) before keys can be assigned.
  • Keys are arbitrary strings, set with array[key]=value, and can include spaces if the key is quoted.
  • Iterate keys with "${!array[@]}" and values with ${array[$key]}; iteration order is not guaranteed and must be sorted explicitly for deterministic output.
  • [[ -v array[key] ]] tests whether a key exists, which is different from [[ -n "${array[key]}" ]] testing a non-empty value.
  • Associative arrays are ideal for frequency counters, lookup tables, and set-membership checks.
  • Bash has no native nested/multi-dimensional associative arrays; flatten with composite keys like array["$row,$col"].
  • declare -A requires Bash 4.0+; scripts targeting old default macOS Bash (3.2) need a workaround or a newer Bash install.

Practice what you learned

Was this page helpful?

Topics covered

#Bash#AdvancedBashScriptingStudyNotes#DevOps#AssociativeArrays#Associative#Arrays#Declaring#Iteration#DataStructures#StudyNotes#SkillVeris