Indirekte Parametererweiterung im assoziativen Array

Sep 23 2020

Nach dieser Antwort möchte ich den Ansatz auf mein Skript anwenden. Die Grundlagen davon sind:

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

Ich möchte übersetzte Zeichenfolgen wie folgt bereitstellen:

declare -A es
declare -A en

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

Dann würde ich oben in meinem Skript Folgendes festlegen:

lang="es"

dann

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

Ich würde die Ausgabe erwarten:

Hola Mundo

oder

lang="en"

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

Hello World

Aber alles was ich bekomme sind leere Fäden.

Ist das möglich oder sollte ich andere Wege erkunden?


Bisher bin ich mit zwei Ansätzen gekommen, von denen keiner mir gefällt:

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

Das andere:

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

Antworten

4 Kusalananda Sep 23 2020 at 14:09

Verwenden Sie anstelle der Indirektion eine Namensreferenzvariable.

Mit Ihrer anfänglichen Einrichtung der assoziativen Arrays enund es:

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

Der Wert der langNamensreferenz ist der Name einer anderen Variablen. Der Zugriff auf die Variable entspricht langdem Zugriff auf die benannte Variable.

Namensreferenzvariablen sind bashseit Release 4.3 in der Shell verfügbar .