Reputation: 448
I've been wrestling with this problem for a long time and can't seem to find a working solution.
Suppose I have declared two associative arrays.
declare -A FOO_ARRAY=(
[a]="first"
[b]="second"
[c]="third"
)
declare -A BAR_ARRAY=(
[a]="first"
[b]="second"
[c]="third"
)
I can get a list of keys like so:
$ echo ${!FOO_ARRAY[@]}
c b a
$ echo ${!BAR_ARRAY[@]}
c b a
I can also dynamically deference a key from the array by doing something like this:
for KEY in FOO BAR
do
temp="${KEY}_ARRAY[a]"
echo ${!temp}
done
However, if you notice that the operator for dynamically referencing variables is also the same to get the list of keys from an associative array, how could I make something like this possible in order to dynamically list the keys in an associative array?
A naive example like this results in an invalid variable name
error.
$ export NAME=foo
$ export temp="\!${NAME^^}_ARRAY[@]"
$ echo ${!temp}
bash: \!FOO_ARRAY[@]: invalid variable name
What I'm searching for is a way to dynamically return the list of keys from an associative array as if the above code sample returned:
c b a
Upvotes: 1
Views: 1769
Reputation: 32997
Use declare -n
. From help declare
:
-n make NAME a reference to the variable named by its value
Example:
declare -A foo_array=(
[a]="first"
[b]="second"
[c]="third"
)
declare -n temp="foo_array"
echo "${!temp[@]}" # -> a b c
For more details, see info bash
under the "Bash Builtins" section.
Upvotes: 3
Reputation: 123490
You can use a nameref
:
declare -rgA FOO_ARRAY=(
[a]="first"
[b]="second"
[c]="third"
)
name="foo"
declare -n array="${name^^}_ARRAY"
echo "The keys are: " "${!array[@]}"
Upvotes: 3
Reputation: 916
This Will Work
NAME=foo
temp="${NAME^^}_ARRAY[@]"
echo ${!temp}
Explanation: here temp will store " FOO_ARRAY[@] " as string only and when echo it in reference way it does print the value.
Example
declare -rgA FOO_ARRAY=(
[a]="first"
[b]="second"
[c]="third"
)
declare -rgA BAR_ARRAY=(
[a]="first"
[b]="second"
[c]="third"
)
echo ${!FOO_ARRAY[@]}
echo ${!BAR_ARRAY[@]}
for KEY in FOO BAR
do
temp="${KEY}_ARRAY[a]"
echo ${!temp}
done
NAME=foo
temp="${NAME^^}_ARRAY[@]"
echo ${!temp}
Run:
a b c
a b c
first
first
first second third
Upvotes: 0