"erro de matriz incorreta" ao adicionar entrada a um array associativo

1

Eu achei melhor começar uma nova consulta, já que minha consulta original foi totalmente respondida (obrigado!).

Eu tenho dois arquivos que são ambos saídas de um comando postgresql. O primeiro (/tmp/inventory.list) foi o assunto da minha consulta original converter a tabela para o arquivo ini usando o bash arrays , para o qual estou usando o comando array gentilmente sugerido por @choroba. Dado que o formato do meu segundo arquivo (/tmp/inventory2.list) é muito parecido com o primeiro, achei que poderia adaptar o script da matriz para processar esse arquivo de forma semelhante, mas estou obviamente estragando algo.

Meu arquivo de entrada /tmp/inventory2.list está no formato:

environment1 | hostname1.environment1.domain
environment1 | hostname2.environment1.domain
environment1 | hostname3.environment1.domain
environment2 | hostname4.environment2.domain
environment2 | hostname5.environment2.domain
environment3 | hostname6.environment3.domain

Isso deve ser lido e gravado em outro arquivo no formato agrupado:

[environment1]
hostname1.environment1.domain
hostname2.environment1.domain
hostname3.environment1.domain

[environment2]
hostname4.environment2.domain
hostname5.environment2.domain

[environment3]
hostname6.environment3.domain

Tem que haver um espaço de linha entre os agrupamentos de ambiente, os nomes dos grupos devem ser exibidos em ordem alfabética e os nomes de host devem ser classificados em ordem alfabética dentro dos grupos. Pode haver muitos nomes de host para cada grupo de ambiente, mas cada grupo deve ser exibido apenas uma vez.

Para complicar as coisas, há uma linha em branco no final do arquivo de entrada, que não consigo deixar minha consulta postgresql deixar de fora (-t ou --tuples-only remove a linha de contagem de linhas normalmente escrita no final, mas não remove a última linha em branco), então isso precisa ser removido e não gravado no novo arquivo de saída.

Eu tentei adaptar o comando array @ choroba para ler este arquivo e reproduzi-lo corretamente, mas embora funcione perfeitamente para o meu primeiro arquivo, minha adaptação não funciona. Eu tenho:

  1 #! /bin/bash
  2
  3 unset -v envs
  4 unset -v hosts
  5 declare -A envs
  6 declare -A hosts
  7 rm -f /tmp/hosts.txt
  8
  9 while IFS='| ' read -r certname role env; do
 10     envs["$role.$env"]+="$certname"$'\n'
 11 done < /tmp/inventory.list
 12
 13 for e in "${!envs[@]}" ; do
 14 #
 15     printf '%s\n' "$e"
 16 done | sort | while read -r e ; do
 17     printf '%s\n' "[$e]" "${envs[$e]}" >> /tmp/hosts.txt
 18 done
 19
 20 while IFS='| ' read -r env certname; do
 21     hosts["$env"]+="$certname"$'\n'
 22 done < /tmp/inventory2.list
 23
 24 for f in "${!hosts[@]}" ; do
 25     printf '%s\n' "$f"
 26 done | sort | while read -r f ; do
 27     printf '%s\n' "[$f]" "${hosts[$f]}" >> /tmp/hosts1.txt
 28 done

As linhas 9 a 18 (e as linhas associadas 3 e 5) foram o código dado por @choroba e funcionam perfeitamente no arquivo lido em /tmp/inventory.list.

As linhas 20 a 28 (e as linhas associadas 4 e 6) são minha adaptação para lidar com este segundo arquivo, /tmp/inventory2.list. Quando executado, recebo o erro:

 line 21: hosts["$env"]: bad array subscript

Eu mexi com isso por horas, mas não consigo ver o que está errado no meu snippet adaptado. Alguém tem algum pensamento, por favor?

    
por HelenH 13.01.2016 / 13:24

1 resposta

4

Você menciona uma linha em branco em um arquivo de entrada; se estiver em /tmp/inventory2.list, então esse é o problema.

Trabalhe de várias maneiras; um seria testar a variável $ env antes de tentar usá-la:

[ -n "$env" ] && hosts["$env"]+="$certname"$'\n'

Outro seria o grep para qualquer caractere no arquivo antes de lê-lo:

grep . inventory2.list | while IFS='| ' read -r env certname; do
  hosts["$env"]+="$certname"$'\n'
done

(ajuste o grep se sua linha "em branco" tiver espaços; algo como grep [a-z] )

    
por 13.01.2016 / 14:52

Tags