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?


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

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.