An associative array stores values under text keys instead of numbered positions. Bash 4.0 and newer support them.
On macOS, that may mean upgrading the system Bash before running these examples.
Here is an array that uses first names as keys and last names as values:
declare -A names=(
[John]=Doe
[Jane]=Doe
[Jim]=Smith
[Angela]=Merkel
)The capital -A tells Bash that names is an associative array. Lowercase -a
would create a regular indexed array instead.
Each entry has a key and a value:
┌── array name
| ┌── array value
┌─┴─┐ ┌┴┐
names[John]=Doe
└──┬─┘
└── array keyYou can also declare the array first and add entries later:
declare -A names
names[John]=Doe
names[Jane]=Doe
names[Jim]=Smith
names[Angela]=MerkelRead a value
Use its key to read a value:
printf '%s\n' "${names[John]}"
# DoeQuote array expansions. This keeps spaces and wildcard characters in keys or values from being treated as shell syntax.
Loop over the array
${!names[@]} expands to all keys. Use each key to read its matching value:
for first_name in "${!names[@]}"; do
last_name=${names[$first_name]}
printf '%s : %s\n' "$first_name" "$last_name"
doneOne possible output is:
John : Doe
Jane : Doe
Jim : Smith
Angela : MerkelThe order may differ between runs or Bash versions.
Find keys by value
Associative arrays are made for looking up a value by its key, not the other way around. More than one key can also have the same value: both John and Jane map to Doe in this example. To find matching keys, loop over the array:
wanted_last_name=Doe
for first_name in "${!names[@]}"; do
if [[ ${names[$first_name]} == "$wanted_last_name" ]]; then
printf '%s\n' "$first_name"
fi
doneThis prints John and Jane, though their order is not guaranteed.
Add, change, and remove entries
Assigning a new key adds an entry:
names[Zaphod]=BeeblebroxAssigning an existing key changes its value:
names[John]=SmithRemove an entry with unset. Quote the argument so the brackets are not read as
a filename pattern:
unset 'names[Jim]'Associative arrays do not have a fixed order, so adding an entry does not append it to an "end."
Keys and values with spaces
Quote keys and values that contain spaces:
declare -A couples=(
["John Doe"]="Jane Doe"
["David Hasselhoff"]="Angela Merkel"
)
person="John Doe"
printf '%s\n' "${couples[$person]}"
# Jane DoeTo read Bash's full documentation for arrays, run:
$ man bashThen search for Arrays inside the manual.