Wie kann man ein assoziatives Bash-Array in eine Textdatei umrunden?

9

Ich möchte ein assoziatives Array zwischen verschiedenen Skriptläufen auswendig lernen. Was ich bisher habe, ist die gegebene Textdatei, die ein Schlüssel / Wert-Paar enthält:

(
[james]=bond
)

Ist ein Skript, um das in ein assoziatives Array zu laden, es hinzuzufügen und es dann auf eine Weise wiederzugeben, die in eine zweite Datei umgeleitet werden kann:

#!/bin/bash
file=`cat $1`
key=$2
value=$3
declare -A row="$file"
row[$key]=$value
echo "("
for server in "${!row[@]}"
    do echo "[$server]=${row[$server]}"; done
echo ")"

dann kann ich es ausführen als:

./arrays.sh file1 honey rider > file2 ; mv file2 file1

Geben

(
[james]=bond
[honey]=rider
)

Dennoch scheint es sehr klobig. Gibt es einen saubereren Weg, dies zu tun?

simbo1905
quelle
4
declare -p hash > fileum das hashassoziative Array zu speichern . source fileetwas wiederherstellen.
Stéphane Chazelas
2
Es sollte wahrscheinlich sein arrays.bash...
Mikesserv

Antworten:

10

In bash, declare -pverwendet werden kann , die Definition einer Variablen als Shell - Code - Dump bereit zu interpretieren, so dass Sie mit Aktualisierungen der Datei tun können:

#! /bin/bash -
file=${1?}; shift
declare -A row
source -- "$file" || exit
while [ "$#" -ge 2 ]; do
  row[$1]=$2
  shift 2
done
declare -p row > "$file"

Beachten Sie, dass es wichtig ist, dass die Datei im selben Gebietsschema (mindestens in derselben LC_CTYPEKategorie) generiert und bezogen wird .

Ein Skript zum Anzeigen des Inhalts der Datei wäre:

#! /bin/bash -
file=${1?}; shift
declare -A row
source -- "$file"
for i in "${!row[@]}"
do
  printf 'key  : %s\n' "$i"
  printf 'value: %s\n' "${row[$i]}"
done
Stéphane Chazelas
quelle
Hurra für selbstqualifizierende Parameter! Aber wäre eine spezifischere Fehlerzeichenfolge nicht nützlicher?
Mikesserv
@mikeserv, klar, aber das geht über den Punkt der Antwort hinaus. Fügen Sie auf jeden Fall die richtige Syntaxprüfung hinzu. Möglicherweise möchten Sie auch überprüfen, ob nach dem Dateinamen eine gerade Anzahl von Argumenten steht (oder das ungerade einzelne Argument als Mittel zum Entfernen eines einzelnen Elements verwenden).
Stéphane Chazelas
Ich weiß nicht ... Bitten Sie mich vielleicht nicht, etwas zu bearbeiten ... Sie sollten die Vampire nicht einladen ... Aber was getan wird, wird getan, denke ich.
Mikesserv
Oh, das tut mir leid. Ich denke, ich hätte das nicht wörtlich nehmen sollen? Ich habe getan, was Sie gefragt haben, und es etwas robuster gemacht, ohne es zu komplizieren.
Mikesserv
2
@ ec2011, mit neueren Versionen von bash(aktueller als zum Zeitpunkt der Erstellung der Antwort verfügbar) können Sie readarray -td '' arrayNUL-getrennte Datensätze in ein reguläres Array lesen und dann in ein assoziatives Array konvertieren.
Stéphane Chazelas