30 Stimmen

Several changes needed to be done in the HTML tags. Here is the translation: ```html <html> <body> <h1>Mehrdimensionale assoziative Arrays in Bash</h1> </body&g

Ich versuche, ein mehrdimensionales assoziatives Array zu erstellen, aber benötige Hilfe. Ich habe die auf der SO-Seite vorgeschlagene Seite überprüft, aber sie hat mich noch mehr verwirrt. Bisher habe ich folgendes:

Das Skript:

#!/bin/bash
declare -A PERSONS
declare -A PERSON
PERSON["FNAME"]='John'
PERSON["LNAME"]='Andrew'
PERSONS["1"]=${PERSON[@]}
PERSON["FNAME"]='Elen'
PERSON["LNAME"]='Murray'
PERSONS["2"]=${PERSON[@]}
for KEY in "${!PERSONS[@]}"; do
 TMP="${PERSONS["$KEY"]}"
 echo "$KEY - $TMP"
 echo "${TMP["FNAME"]}"
 echo "${TMP["LNAME"]}"
done

Die Ausgabe:

1 - John Andrew
John Andrew
John Andrew
2 - Elen Murray
Elen Murray
Elen Murray

Wie Sie sehen können, liefert der Versuch, im for-Schleifenindex auf den $TMP-Array zuzugreifen, das gesamte Array zurück.

[Q] Was muss ich tun, um die Indexe "FNAME" und "LNAME" des $TMP-Arrays innerhalb der for-Schleife getrennt anzusprechen?

Danke.

43voto

glenn jackman Punkte 221248

Sie können nicht das tun, was Sie versuchen zu tun: Bash-Arrays sind eindimensional

$ declare -A PERSONS
$ declare -A PERSON
$ PERSON["FNAME"]='John'
$ PERSON["LNAME"]='Andrew'
$ declare -p PERSON
declare -A PERSON='([FNAME]="John" [LNAME]="Andrew" )'
$ PERSONS[1]=([FNAME]="John" [LNAME]="Andrew" )
bash: PERSONS[1]: kann Liste nicht Array-Mitglied zuweisen

Sie können eine Schein-Mehrdimensionalität erzeugen, indem Sie einen passenden Array-Index-String komponieren:

declare -A PERSONS
declare -A PERSON

PERSON["FNAME"]='John'
PERSON["LNAME"]='Andrew'
i=1
for key in "${!PERSON[@]}"; do
  PERSONS[$i,$key]=${PERSON[$key]}
done

PERSON["FNAME"]='Elen'
PERSON["LNAME"]='Murray'
((i++))
for key in "${!PERSON[@]}"; do
  PERSONS[$i,$key]=${PERSON[$key]}
done

declare -p PERSONS
# ==> declare -A PERSONS='([1,LNAME]="Andrew" [2,FNAME]="Elen" [1,FNAME]="John" [2,LNAME]="Murray" )'

9voto

sameer Soni Punkte 91

Ich verstehe, was du brauchst. Das wollte ich auch seit Wochen. Ich war verwirrt, ob ich Python oder Bash verwenden soll. Schließlich, als ich etwas anderes erkundete, fand ich dies Bash: Wie weise ich einem assoziativen Array einen anderen Variablennamen zu (z. B. benenne die Variable um)?

Hier habe ich gelernt, wie Sie einige Zeichenfolgen zuweisen und sie später als Befehl verwenden können. Dann habe ich mit meiner Kreativität eine Lösung für dein Problem gefunden:


#!/bin/bash

declare -A PERSONS
declare -A PERSON

PERSON["FNAME"]='John'
PERSON["LNAME"]='Andrew'
string=$(declare -p PERSON)
#printf "${string}\n"
PERSONS["1"]=${string}
#echo ${PERSONS["1"]}

PERSON["FNAME"]='Elen'
PERSON["LNAME"]='Murray'
string=$(declare -p PERSON)
#printf "${string}\n"
PERSONS["2"]=${string}
#echo ${PERSONS["2"]}

for KEY in "${!PERSONS[@]}"; do
   printf "$KEY - ${PERSONS["$KEY"]}\n"
   eval "${PERSONS["$KEY"]}"
   printf "${PERSONS["$KEY"]}\n"
   for KEY in "${!PERSON[@]}"; do
      printf "INSIDE $KEY - ${PERSON["$KEY"]}\n"
   done
done

AUSGABE:-

1 - declare -A PERSON='([FNAME]="John" [LNAME]="Andrew" )'

declare -A PERSON='([FNAME]="John" [LNAME]="Andrew" )'

INSIDE FNAME - John

INSIDE LNAME - Andrew

2 - declare -A PERSON='([FNAME]="Elen" [LNAME]="Murray" )'

declare -A PERSON='([FNAME]="Elen" [LNAME]="Murray" )'

INSIDE FNAME - Elen

INSIDE LNAME - Murray


Das Problem besteht tatsächlich bei mehrdimensionalen Arrays in Bash und speziell bei deinem Ansatz ist, dass du die Werte des PERSON-Arrays dem Array-Element PERSONS[1] zuweist, das in eine Liste umgewandelt wird und nicht in ein assoziatives Array, wenn du es zuweist. Deshalb wird es nicht mehr als 2 Elemente eines Arrays betrachten, da du keine Informationen über die Datenstruktur des Arrays in deinem Wert behältst. Also habe ich diesen Hack gefunden, der mit nur einer Einschränkung ausreicht, dass du dies jedes Mal machen musst, wenn du Werte speichern/abrufen möchtest. Aber es wird deinen Zweck erfüllen.

-3voto

Raymondo Punkte 61
#!/bin/bash
declare -A PERSONS
declare -A PERSON
PERSON["FNAME"]='John'
PERSON["LNAME"]='Andrew'
PERSONS["1"]=${PERSON[@]}
PERSON["FNAME"]='Elen'
PERSON["LNAME"]='Murray'
PERSONS["2"]=${PERSON[@]}
for KEY in "${!PERSONS[@]}"; do
 TMP="${PERSONS["$KEY"]}"
 echo "$KEY - $TMP"
 **echo "${PERSON["FNAME"]}"
 echo "${PERSON["LNAME"]}**"
done

Denn das ursprüngliche Array für die separaten Namen ist immer noch aktiv und kann immer noch innerhalb der Schleife for referenziert werden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X