In this very simplified example, I need to address both key and value of an array element:
declare -A writer
writer[H.P.]=Lovecraft
writer[Stephen]=King
writ
Since Bash 4.3, declare
has a flag -n
to define references (this is loosely equivalent to references in C++). This flag tremendously simplifies your problem here:
fullname() {
declare -nl pointer="$1"
for i in "${!pointer[@]}"
do
echo "${pointer[$i]} $i"
done
}
It will be safe if you're having spaces or funny symbols in the keys of your hash (unlike the accepted answer).
indir_keys() {
eval "echo \${!$1[@]}"
}
indir_val() {
eval "echo \${$1[$2]}"
}
fullname()
{
pointer=$1
for i in $(indir_keys $pointer)
do
echo "$i $(indir_val $pointer $i)"
done
}
Gives:
Jack Ketchum
Clive Barker
Stephen King
H.P. Lovecraft
From the Bash Reference Guide:
The positional parameters are temporarily replaced when a shell function is executed (see Shell Functions).
So you could do this:
fullname()
{
for first
do
echo "$first ${writer[$first]}"
done
}
fullname "${!writer[@]}"