#!/usr/bin/bash
ARGENT=("Nous devons économiser de l'argent."
"Je dois économiser de l'argent.")
BIENETRE=("Comment vas-tu?" "Tout va bien ?")
aoarrs=("${ARGENT}" "${BIENETRE}")
select arr in "${aoarrs[@]}"; do
for el in "${arr[@]}"; do
echo "$el"
done
break
done
Quero que este script imprima os nomes dos arrays para o usuário, ARGENT
e BIENETRE
, para que o usuário possa selecionar um deles. Após a entrada do usuário, o script deve imprimir todos os elementos de um array selecionado. Quero selecionar com select
uma matriz para percorrer a partir de uma matriz de matrizes ( aoarrs
). A razão pela qual quero usar select é porque no mundo real meu array de arrays pode ter muito mais do que apenas dois arrays. Como posso conseguir isso?
Você armazenará os nomes
aoarrs
dos arrays e dentro do corpo do select declarará um nameref para o nome escolhido :Correr pode parecer
Você gostaria de um mapeamento de "chaves" para "valores", onde "valores" são as listas de strings e as "chaves" são
ARGENT
,BIENETRE
…Você está no caminho certo
aoarrs
, porque poderia usar esse array como array associativo:e então iterar sobre todas as chaves desse array usando algo como
for key in ${!aoarrs[@]}…
.Infelizmente , o bash não permite, por qualquer motivo, que listas sejam elementos dessas matrizes associativas.
Então, as coisas são péssimas. Você pode, por exemplo, juntar os elementos de suas listas com um caractere reservado para dividi-los mais tarde (isso é estúpido porque significa que você não pode ter todos os caracteres em sua string ou precisa começar a escapar deles), ou você pode construir suas próprias funções que pegam listas de strings, acrescentam-nas a um array grande e então você implementa sua própria função de pesquisa associativa nesse contêiner (isso seria estúpido; além de ser lento, também exigiria que você escrevesse relativamente muito código de uma forma relativamente linguagem inadequada). Seria terrível. Aqui está um exemplo que escrevo sem testá-lo, porque é feio o suficiente para que eu precise tirá-lo da cabeça, mas não quero mais lidar com isso:
A próxima opção é mágica que envolve "endereçamento indireto" de variáveis por nome usando
eval
. Isso é meio malvado e estúpido, e há muitos posts aqui que sugerem "se você está nesse ponto, talvez use uma linguagem de programação adequada em vez do bash".Eu concordo com isso : todo esse problema seria literalmente feito em quatro linhas de python, com as duas primeiras linhas armazenando "ARGENT" e "BIENETRE" e suas listas em um arquivo
dict
. Ou, na verdade, em qualquer outra linguagem comum que não seja bash (ou C, nesse caso), matrizes associativas são menos ruins.A matriz abrangente possui apenas nomes de variáveis:
declare -n ref=$arr
- faça uma referência à variável nomeada pelo seu valor.break 2
- quebre 2 loops envolventes.Seria mais fácil no ksh93 (o shell bash tenta emular), onde matrizes associativas podem ter matrizes (entre outras coisas) como valores.