Jonathan
Jonathan

Reputation: 11365

Bash , use variable as name of associative array when calling value

This question bad substitution shell- trying to use variable as name of array does something similar to what I need but for arrays. I'm very new to bash scripting and what I need is to do something like this:

# input
humantocheck="human1"

declare -A human1
declare -A human2

human1=( ["records_file"]="xxxxx.txt")
human2=( ["records_file"]="yyyyy.txt")

echo ${$humantocheck[records_file]}

With expected output of:

xxxxx.txt

However I get a bad substitution error when I try this.

Upvotes: 5

Views: 3208

Answers (2)

pjh
pjh

Reputation: 8104

One way to do this with an indirect reference is:

ref=$humantocheck[records_file]
echo ${!ref}

Bash: Indirect Expansion Exploration is an excellent reference for indirect access to variables in Bash.

Note that the echo command, which was intended to be a minimal modification to the original code, is unsafe in several ways. A safe alternative is:

printf '%s\n' "${!ref}"

See Why is printf better than echo?.

Upvotes: 3

Charles Duffy
Charles Duffy

Reputation: 295472

This is exactly the scenario that the bash 4.3 feature namevars (borrowed from ksh93) is intended to address. Namevars allow assignment, as opposed to lookup alone, and are thus more flexible than the ${!foo} syntax.

# input
humantocheck="human1"

declare -A human1=( ["records_file"]="xxxxx.txt" )
declare -A human2=( ["records_file"]="yyyyy.txt" )

declare -n human=$humantocheck # make human an alias for, in this case, human1
echo "${human[records_file]}"  # use that alias
unset -n human                 # discard that alias

See BashFAQ #6 for a comprehensive discussion of both associative arrays and indirect expansion in general.

Upvotes: 9

Related Questions