Você está usando essa construção:
b=("${!arrname}")
Isso expande os valores da matriz, criando uma nova matriz b[]
com os índices padrão da matriz bash a partir de 0 . Para inicializar corretamente uma cópia da matriz, você
precisa restaurar os índices (por exemplo, parsing ou eval
-ing a saída de declare -p arrname
)
Em vez de fazer uma cópia, uma abordagem melhor é expandir os índices em vez dos valores e iterar pelo array usando-os. Essa abordagem funcionará com matrizes padrão esparsas ou não baseadas em zero (e até matrizes associativas bash4).
A pegadinha (não é sempre) é que o !
está ganhando o dever duplo: seu uso indireto ${!name}
não é compatível com seu uso para expandir índices de array ${!arrname[@]}
, então temos que usar eval
.
Aqui está uma versão modificada que implementa isso:
getIndex2() {
local arrname=$1 iidx idxs index ival val
printf -v iidx '"${!%s[@]}"' "$arrname"
eval "idxs=($iidx)"
for index in "${idxs[@]}"; do
printf -v ival '${%s[%s]}' "$arrname" "$index"
eval "val=$ival"
if [[ "${val}" = "$VALUE" ]]; then
echo "index is $index"; return
fi
done
}
Observe o uso de printf -v var ...
(bash-3.1 +) para tentar manter o eval
legível.
Os índices são expandidos em uma matriz, isso não é estritamente necessário, uma lista simples também faria.
Veja também BashFAQ / 006 .