comment aller-retour d'un tableau associatif bash à un fichier texte?

9

Je souhaite mémoriser un tableau associatif entre différentes exécutions de script. Ce que j'ai jusqu'à présent, c'est que, étant donné un fichier texte contenant une paire clé / valeur:

(
[james]=bond
)

Est un script pour charger cela dans un tableau associatif, y ajouter, puis l'écho d'une manière qui peut être redirigée dans un deuxième fichier:

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

alors je peux l'exécuter comme:

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

Donnant

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

Pourtant, cela semble très maladroit. Existe-t-il une façon plus propre de procéder?

simbo1905
la source
4
declare -p hash > filepour enregistrer le hashtableau associatif. source filerestaurer.
Stéphane Chazelas
2
Cela devrait probablement être arrays.bash...
mikeserv

Réponses:

10

Dans bash, declare -ppeut être utilisé pour vider la définition d'une variable sous forme de code shell prêt à être interprété, vous pouvez donc effectuer des mises à jour du fichier avec:

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

Notez qu'il est important que le fichier soit généré et obtenu dans le même environnement local (au moins la même LC_CTYPEcatégorie).

Un script pour afficher le contenu du fichier serait:

#! /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
la source
Hourra pour les paramètres d'auto-qualification! Mais une chaîne d'erreur plus spécifique ne serait-elle pas plus utile?
mikeserv
@mikeserv, bien sûr, mais c'est au-delà du point de la réponse. Par tous les moyens, veuillez ajouter une vérification de syntaxe appropriée, le cas échéant. On peut également vouloir vérifier qu'il y a un nombre pair d'arguments après le nom du fichier (ou utiliser l'argument unique impair comme moyen de supprimer un seul élément).
Stéphane Chazelas
Je sais pas ... Peut-être ne me demandez pas de modifier ... Vous n'êtes pas censé inviter les vampires ... Mais ce qui est fait est fait, je suppose.
mikeserv
Oh pardon. Je suppose que je n'aurais pas dû prendre ça au pied de la lettre? J'ai fait comme vous l'aviez demandé et je l'ai rendu un peu plus robuste sans le compliquer.
mikeserv
2
@ ec2011, avec les versions récentes de bash(plus récentes que celles disponibles au moment de la rédaction de la réponse), vous pourriez utiliser readarray -td '' arraypour lire les enregistrements délimités NUL dans un tableau normal , puis les convertir en tableau associatif.
Stéphane Chazelas