como ida e volta de uma matriz associativa bash para um arquivo de texto?

9

Eu quero memorizar uma matriz associativa entre diferentes execuções de script. O que tenho até agora é que, dado um arquivo de texto contendo um par de chave / valor:

(
[james]=bond
)

É um script para carregar isso em um array associativo, adicioná-lo e repeti-lo de uma maneira que possa ser redirecionada para um segundo arquivo:

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

então eu posso executá-lo como:

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

Dando

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

No entanto, parece muito desajeitado. Existe uma maneira mais limpa de fazer isso?

simbo1905
fonte
4
declare -p hash > filepara salvar a hashmatriz associativa. source filerestaurar.
Stéphane Chazelas
2
Provavelmente deve ser arrays.bash...
mikeserv

Respostas:

10

Em bash, declare -ppode ser usado para despejar a definição de uma variável como código de shell pronto para ser interpretado, para que você possa fazer atualizações no arquivo com:

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

Observe que é importante que o arquivo seja gerado e originado no mesmo local (pelo menos na mesma LC_CTYPEcategoria).

Um script para mostrar o conteúdo do arquivo seria:

#! /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
fonte
Viva os parâmetros de auto-qualificação! Mas uma sequência de erros mais específica não seria mais útil?
mikeserv
@ MikeServ, claro, mas isso está além do ponto da resposta. Por todos os meios, adicione a verificação de sintaxe adequada, conforme apropriado. Pode-se também verificar se há um número par de argumentos após o nome do arquivo (ou usar o argumento único ímpar como forma de remover um único elemento).
Stéphane Chazelas
Não sei ... Talvez não me peça para editar ... Você não deveria convidar os vampiros para ... Mas o que está feito está feito, eu acho.
mikeserv
Oh, desculpe. Eu acho que não deveria ter entendido isso literalmente? Fiz o que você pediu e o tornou um pouco mais robusto sem complicar.
mikeserv
2
@ ec2011, com versões recentes de bash(mais recente do que estava disponível no momento em que a resposta foi escrita), você poderá usar readarray -td '' arraypara ler registros delimitados por NUL em uma matriz regular e depois convertê-los em uma matriz associativa.
Stéphane Chazelas