3

Following this answer, I want to apply the approach on my script. The basics of it is:

foo="bar" 
baz="foo"
echo "${!baz}"
bar

I want to provide translated strings, like this:

declare -A es
declare -A en

#
es["greet"]="Hola"
en["greet"]="Hello"
#
es["world"]="Mundo"
en["world"]="World"

Then at the top of my script I would set:

lang="es"

then

echo "${!lang["greet"]} ${!lang["world"]}"

I would expect the output:

Hola Mundo

or

lang="en"

echo "${!lang["greet"]}" "${!lang["world"]}"

Hello World

But all I get are empty strings.

Is it possible to do this or should I explore other ways?


So far I've come with two approaches, none of them I like:

declare -A hello
hello["es"]="Hola"
hello["en"]="Hello"

declare -A world
world["es"]="Mundo"
world["en"]="World"

lang="es"

echo "${hello[$lang]} ${world[$lang]}"
Hola Mundo

The other:

lang="es"

if [[ "$lang" = "es" ]]; then
  declare -A language=(
    ["greet"]="Hola"
    ["world"]="Mundo"
  )
elif [[ "$lang" = "en" ]]; then
  declare -A language=(
    ["greet"]="Hello"
    ["world"]="World"
  )
fi

echo "${language["greet"]} ${language["world"]}"
Hola Mundo
4

Use a name-reference variable instead of indirection.

With your initial set-up of the associative arrays en and es:

$ declare -n lang=en
$ echo "${lang["greet"]} ${lang["world"]}"
Hello World
$ declare -n lang=es
$ echo "${lang["greet"]} ${lang["world"]}"
Hola Mundo

The value of the lang name-reference is the name of another variable. Accessing the variable lang will be the same as accessing that named variable.

Name-reference variables are available in the bash shell since release 4.3.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.