come round trip un array associativo bash in un file di testo?


9

Voglio memorizzare un array associativo tra diverse esecuzioni di script. Quello che ho finora è che dato un file di testo contenente una coppia chiave / valore:

(
[james]=bond
)

È uno script per caricarlo in un array associativo, aggiungerlo ad esso, quindi riecheggiarlo in un modo che può essere reindirizzato in un secondo file:

#!/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 ")"

quindi posso eseguirlo come:

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

Dando

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

Eppure sembra molto goffo. C'è un modo più pulito per farlo?


4
declare -p hash > fileper salvare l' hasharray associativo. source fileripristinare.
Stéphane Chazelas,

2
Probabilmente dovrebbe essere arrays.bash...
Mikeserv il

Risposte:


10

In bash, declare -ppuò essere usato per scaricare la definizione di una variabile come codice shell pronto per essere interpretato, in modo da poter fare aggiornamenti al file con:

#! /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"

Si noti che è importante che il file sia generato e acquistato nella stessa locale (almeno nella stessa LC_CTYPEcategoria).

Uno script per mostrare il contenuto del file sarebbe:

#! /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

Evviva i parametri auto-qualificanti! Ma una stringa di errore più specifica non sarebbe più utile?
Mikeserv,

@mikeserv, certo, ma è oltre il punto della risposta. Sicuramente, si prega di aggiungere un adeguato controllo della sintassi come appropriato. Si potrebbe anche voler verificare che ci sia un numero pari di argomenti dopo il nome del file (o utilizzare l'argomento singolo dispari come mezzo per rimuovere un singolo elemento).
Stéphane Chazelas,

Non so ... Forse non chiedermi di modificare ... Non dovresti invitare i vampiri a ... Ma quello che è fatto è fatto, immagino.
Mikeserv,

Oh scusa. Immagino che non avrei dovuto prenderlo alla lettera? Ho fatto quello che mi hai chiesto e l'ho reso un po 'più robusto senza complicarlo.
Mikeserv,

2
@ ec2011, con le versioni recenti di bash(più recenti di quanto era disponibile al momento della stesura della risposta) saresti in grado di utilizzare readarray -td '' arrayper leggere i record delimitati da NUL in un array normale e quindi convertirlo in un array associativo.
Stéphane Chazelas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.