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?