fny
fny

Reputation: 33635

Properly Specify an Array and Element through Variables in a Shell Script

Consider the following nonsense array:

# KIND[ID]=NAME
MONKEYS[1]="Oo Oo"
MONKEYS[2]="Aa Aa"
MONKEYS[3]="Ba Nana"
LIONS[5]="Mister Mufasa"
LIONS[7]="Cocoa Puff"
LIONS[8]="Lala Leo"
TIGERS[13]="Ben Gal"
TIGERS[15]="Tee Eye Double Guh Err"
TIGERS[22]="Oh Esex Diez Punto Cuatro"

With a given KIND and ID, I'm attempting to build a string that resembles $NAME[$ID] to get the associated name.

When explicitly stating an array name, the command behaves as expected echo "${LIONS[5]}"=>"Mister Mufasa"). However, whenever a variable is used, the shell responds with the given character in the string.

$LIONS[5] => 'e' # The fifth letter in "Mister Mufasa"

In other cases, I can't find a way to control interpolation to get the NAME

KIND="LIONS"
ID="5"

# Attempt to return value of `LIONS` when `KIND=LIONS`
echo $"${KIND}"; echo "\$${KIND}" #=> "$LIONS"
echo "$${KIND}" #=> "57800{KIND}" Interpolates "$$"
echo "\$\${KIND}"; "\$\${KIND}" #=> "$${KIND}"

I found the following works albeit "ugly"...

eval echo `echo \\$${KIND}`

However when introducing the ID things break once again:

eval echo `echo \\$${KIND}[$ID]`
#> title:5: no matches found: $LIONS[5]
#> no matches found: $LIONS[5]

I feel like I'm missing something very simple. I have a hunch I'm forgetting to escape something, but I'm not quite sure what.

Also, what "less redundant" alternatives to eval echo `echo... or eval echo `print... exist?

Upvotes: 0

Views: 452

Answers (1)

Gordon Davisson
Gordon Davisson

Reputation: 126108

In bash, use indirect addressing:

REF="$KIND[$ID]" # Sets REF to "LIONS[5]"
echo "${!REF}"   # Prints "Mister Mufasa"

EDIT: In zsh, use nested expansion instead:

echo "${(P)${KIND}[ID]}"

Upvotes: 2

Related Questions