В bash
4.3 или новее можно использовать переменные nameref:
for t in "${!gopath[@]}"; do
(
typeset -n current="${t}_obj"
cd -P -- "${gopath[$t]}" || exit
for k in "${!current[@]}"
do
printf '%s\n' "[$t]key is: $k; value is: ${current[$k]}"
done
)
done
В более старых версиях вам нужно будет использоватьeval
:
for t in "${!gopath[@]}"; do
(
cd -P -- "${gopath[$t]}" || exit
eval '
for k in "${!'"$t"'_obj[@]}"
do
printf "%s\n" "[$t]key is: $k; value is: ${'"$t"'_obj[$k]}"
done
'
)
done
bash
имеет оператор переменной косвенности :${!varname}
, не связанный с оператором ${!hash[@]}
(и на самом деле ближе к обратному тому, что ${!varname}
есть в ksh93 ), но его нельзя комбинировать с оператором ${!hash[@]}
оператор(varname=hash; for key in "${!!varname[@]}"...
не будет работать ). Для оболочки с используемым оператором косвенной переменной здесь (и которая поддерживает ассоциативные массивы намного дольше ), вы можете посмотретьzsh
(с помощью ${(P)varname}
), который также позволяет вам циклически перебирать как ключ, так и значение одновременно. время:
typeset -A start_obj end_obj gopath
start_obj=(
one start-obj-one
two start-obj-two
)
end_obj=(
one end-obj-one
two end-obj-two
)
gopath=(
start /path/to/start
end /path/to/end
)
for t dir ("${(kv@)gopath}") (
cd -P -- "$dir" || exit
current=${t}_obj
for key value ("${(kvP@)current}")
printf '%s\n' "[$t]key is: $key; value is: $value}"
)
В любом случае, и в bash
, и в zsh
(, и в ksh93
первой оболочке, которая представила ассоциативные массивы и которую bash
пытались скопировать ), ассоциативные массивы реализованы в виде хэш-таблиц, поэтому элементы не хранятся в каком-либо определенном порядке, поэтому приведенный выше код будет перебирать их в цикле, казалось бы, в случайном порядке.