Esse pode ser o código Bash mais feio que eu já escrevi, mas ...
IPv4_first=1.1.1.1
IPv4_second=2.2.2.2
IPv4_third=3.3.3.3
names=(${!IPv4_@})
eval "IPv4_all=(${names[@]/#/$})"
printf "'%s'\n" "${IPv4_all[@]}"
Olhe Ma, sem loop!
${names[@]/#/$}
prepends $
para o início de cada elemento da matriz, combinando uma string vazia ancorada no início de cada elemento. Isso fornece uma matriz de desreferências variáveis, que podemos expandir dentro de eval
para obter as referências de variáveis dentro do inicializador de array. Estes precisam ser duas linhas separadas porque você não pode aplicar expansões de múltiplos parâmetros ao mesmo tempo.
A saída é:
'1.1.1.1'
'2.2.2.2'
'3.3.3.3'
como esperado.
É possível substituir a linha por:
IPv4_all=($(eval "echo ${names[@]/#/$}"))
em vez de eval
a atribuição da matriz. Não tenho certeza se isso é melhor ou não.
Se os valores das variáveis puderem conter espaços ou outros caracteres IFS, você poderá alterar o eval:
eval "IPv4_all=($(printf '"$%s" ' "${names[@]}"))"
Isso duplamente aspas todas as desreferências de variáveis.