Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you assign associative arrays to variables in bash?

Tags:

bash

I have a few different associative arrays as variables:

declare -A FIRST=( [hello]=world [foo]=bar )
declare -A SECOND=( [bonjour]=monde [fu]=ba )

What I'd like to be able to do is take a third variable and assign it to one or the other, something like:

usethisarray=$FIRST

or maybe

declare -a usethisarray=$FIRST

But neither of those really work. Can I get a level of indirection to point at the associative array I need?

like image 900
maxst Avatar asked Sep 06 '25 16:09

maxst


2 Answers

Note to readers: this answer is from 2013. You should now be using @ryenus's answer.


bash has variable indirection but it's kind of a pain to use:

$ declare -A FIRST=( [hello]=world [foo]=bar )
$ alias=FIRST
$ echo "${!alias[foo]}"

$ item=${alias}[foo]
$ echo ${!item}
bar
like image 162
glenn jackman Avatar answered Sep 09 '25 08:09

glenn jackman


The answer is yes, and the reference variable needs to be a nameref (declare -n) for it to be used with arrays:

declare -A FIRST=( [hello]=world [foo]=bar )
declare -A SECOND=( [bonjour]=monde [fu]=ba )

#### ordinary variable assignment does NOT work
declare any_var=FIRST
echo -e '${any_var[@]}:' "${any_var[@]}"
echo -e '${!any_var[@]}:' "${!any_var[@]}"
echo -e '${#any_var[@]}:' "${#any_var[@]}"

#### nameref works, via 'declare -n' or 'local -n'
declare -n arr_ref=SECOND
echo '${arr_ref[@]}:' "${arr_ref[@]}"
echo '${!arr_ref[@]}:' "${!arr_ref[@]}"
echo '${#arr_ref[@]}:' "${#arr_ref[@]}"

The result:

ordinary variable assignment does NOT work

${any_var[@]}: FIRST
${!any_var[@]}: 0
${#any_var[@]}: 1

nameref works, via 'declare -n' or 'local -n'

${arr_ref[@]}: monde ba     # values of the associative array / map
${!arr_ref[@]}: bonjour fu  # keys of the associative array / map
${#arr_ref[@]}: 2           # size of the associative array / map

See https://www.gnu.org/software/bash/manual/bash.html#Shell-Parameters

Array variables cannot be given the nameref attribute. However, nameref variables can reference array variables and subscripted array variables.

Meanwhile, variable indirection, or more correctly indirect expansion, which also uses the exclamation point (!), it requires the variable or parameter to be NOT a nameref:

If the first character of parameter is an exclamation point (!), and parameter is not a nameref, it introduces a level of indirection.

like image 23
ryenus Avatar answered Sep 09 '25 07:09

ryenus