According to man bash it is possible to assign an associative array with a flat list of key-value pairs:
[…] or a list of words that is interpreted as a sequence of alternating keys and values: name=( key1 value1 key2 value2 ...)
This does work, but it does not work to use an array to get these "alternating keys and values":
name=( "${someArray[@]}" )
Consider this example:
#!/usr/bin/env bash
set -u
#declare -A map=(one ONE two TWO)
array=(one ONE two TWO)
declare -A map=("${array[@]}")
# Workaround with `eval`:
#eval "declare -A map=(${array[@]@Q})"
echo "KEYS:"
printf ' %s\n' "${!map[@]}"
echo "VALUES:"
printf ' %s\n' "${map[@]}"
echo "${#map[@]}"
Actual output:
KEYS:
one ONE two TWO
VALUES:
Expected output:
KEYS:
two
one
VALUES:
TWO
ONE
Why is that so?
Include the array parens in the quoted string to preserve the whitespace between items for the declaration. Also, if keys or values themselves contain whitespace, use
@Qto quote each item:Tested with GNU bash 5.2.21