Bash-скриптинг - перебор "переменных" имен переменных для списка ассоциативных массивов
У меня есть список переменных ассоциативных массивов, которые я хочу перебрать и получить их пары ключ / значение.
Я перебираю один ассоциативный массив, перечисляя все его ключи и получая значения, т.е.
for key in "${!queue1[@]}" do
echo "key : $key"
echo "value : ${queue1[$key]}"
done
Сложность заключается в том, что имена ассоциативных массивов являются переменными переменными, например, учитывая count = 5, ассоциативные массивы будут называться queue1, queue2, queue3, queue4, queue5.
Я пытаюсь заменить приведенную выше последовательность на основе подсчета, но до сих пор каждая комбинация скобок и eval не давала намного больше, чем ошибочные замены. например ниже:
for count in {1,2,3,4,5} do
for key in "${!queue${count}[@]}" do
echo "key : $key"
echo "value : ${queue${count}[$key]}"
done
done
Помощь будет очень ценится!
3 ответа
Трудность здесь связана с тем, что синтаксис для косвенного расширения (${!nameref}
) конфликтует с синтаксисом извлечения ключей из ассоциативных массивов (${!array[@]}
). Мы можем иметь только одно или другое, но не оба.
Осторожно, как я об использовании eval
Я не могу найти способ использовать его для извлечения ключей из косвенно ссылающегося ассоциативного массива:
keyref="queue${count}[@]"
for key in $(eval echo '${!'$keyref'}'); do ... ; done
Однако вы можете избежать eval
и использовать косвенное расширение при извлечении значения из массива с заданным ключом. Обратите внимание, что [key]
суффикс должен быть частью расширения:
valref="queue${count}[$key]"
echo ${!valref}
Чтобы поместить это в контекст:
for count in {1..5} ; do
keyref="queue${count}[@]"
for key in $(eval echo '${!'$keyref'}'); do
valref="queue${count}[$key]"
echo "key = $key"
echo "value = ${!valref}"
done
done
Я смог заставить его работать со следующим скриптом:
for count in {1..5} ; do
for key in $(eval echo '${!q'$count'[@]}') ; do
eval echo '${q'$count"[$key]}"
done
done
Обратите внимание, что он ломается, если какой-либо ключ содержит пробел. Если вы хотите иметь дело со сложными структурами данных, используйте более мощный язык, такой как Perl.
Я думаю, что это может работать (но не проверено). Ключ должен относиться к индексации как к полному имени переменной. (То есть массив queue5
может рассматриваться как последовательность переменных с именем queue5[this]
, queue5[that]
, так далее.)
for count in {1,2,3,4,5} do
assoc="queue$count[@]"
for key in "${!assoc}" do
echo "key : $key"
val="queue$count[$key]"
echo "value : ${!val}"
done
done