On Mon, Dec 22, 2025 at 10:57:05 -0500, Zachary Santer wrote:
> On Mon, Dec 22, 2025 at 10:21 AM Greg Wooledge <[email protected]> wrote:
> >
> > The only known workaround is to abandon this approach entirely, and use
> > @K plus eval instead.
>
> Think the OP would want the @Q parameter transformation in this case,
> actually.
>
> $ declare -a array=(a 1 b 2)
> $ eval "declare -A params=( ${array[@]@Q} )"
> $ declare -p params
> declare -A params=([b]="2" [a]="1" )
I suppose it depends on where you're starting from. If the original
source is an associative array, then you can use the @k (lower case)
expansion to convert it into a list of alternating keys and values:
hobbit:~$ declare -p aa
declare -A aa=([two]="2" ["two and a half"]="2.5" [three]="3" [one]="1" )
hobbit:~$ printf '<%s> ' "${aa[@]@k}"; echo
<two> <2> <two and a half> <2.5> <three> <3> <one> <1>
Naively, then, one might expect to be able to take that list of keys and
values, and use it to reconstruct an associative array. Unfortunately,
that's the part that doesn't work (see previous messages).
If you've already saved the list in an indexed array variable, then
it might make sense to use @Q on the saved list:
hobbit:~$ kv=( "${aa[@]@k}" ); declare -p kv
declare -a kv=([0]="two" [1]="2" [2]="two and a half" [3]="2.5" [4]="three"
[5]="3" [6]="one" [7]="1")
hobbit:~$ eval "declare -A newarray=( ${kv[@]@Q} )"; declare -p newarray
declare -A newarray=([two]="2" ["two and a half"]="2.5" [three]="3"
[one]="1" )
However, if you *haven't* already done an @k expansion on the original
array, and you want the most efficient way to serialize it for later
reconstruction, that's where @K (upper case) comes in handy:
hobbit:~$ kvstring=${aa[*]@K}; declare -p kvstring
declare -- kvstring="two \"2\" \"two and a half\" \"2.5\" three \"3\" one
\"1\" "
hobbit:~$ eval "declare -A newarray=( $kvstring )"; declare -p newarray
declare -A newarray=([two]="2" ["two and a half"]="2.5" [three]="3"
[one]="1" )
Having the array's contents in a string gives some flexibility that
you don't have with an indexed array, e.g. passing it through the
environment.