Оболочки с ассоциативными массивами
Некоторые современные оболочки предоставляют ассоциативные массивы: ksh93, bash ≥4, zsh. В ksh93 и bash, если a
это ассоциативный массив, то "${!a[@]}"
это массив его ключей:
for k in "${!a[@]}"; do
echo "$k -> ${a[$k]}"
done
В zsh этот синтаксис работает только в режиме эмуляции ksh. В противном случае вы должны использовать собственный синтаксис zsh:
for k in "${(@k)a}"; do
echo "$k -> $a[$k]"
done
${(k)a}
также работает, если a
нет пустого ключа.
В zsh вы также можете одновременно k
выполнять v
циклы для eys и alues:
for k v ("${(@kv)a}") echo "$k -> $v"
Оболочки без ассоциативных массивов
Эмуляция ассоциативных массивов в оболочках, в которых их нет, - это гораздо больше работы. Если вам нужны ассоциативные массивы, возможно, пришло время добавить более крупный инструмент, такой как ksh93 или Perl.
Если вам нужны ассоциативные массивы в простой оболочке POSIX, вот способ имитировать их, когда ключи ограничены только символами 0-9A-Z_a-z
(цифры ASCII, буквы и подчеркивание). При этом предположении ключи могут использоваться как часть имен переменных. Приведенные ниже функции воздействуют на массив, идентифицируемый префиксом именования «основа», который не должен содержать двух последовательных подчеркиваний.
## ainit STEM
## Declare an empty associative array named STEM.
ainit () {
eval "__aa__${1}=' '"
}
## akeys STEM
## List the keys in the associatve array named STEM.
akeys () {
eval "echo \"\$__aa__${1}\""
}
## aget STEM KEY VAR
## Set VAR to the value of KEY in the associative array named STEM.
## If KEY is not present, unset VAR.
aget () {
eval "unset $3
case \$__aa__${1} in
*\" $2 \"*) $3=\$__aa__${1}__$2;;
esac"
}
## aset STEM KEY VALUE
## Set KEY to VALUE in the associative array named STEM.
aset () {
eval "__aa__${1}__${2}=\$3
case \$__aa__${1} in
*\" $2 \"*) :;;
*) __aa__${1}=\"\${__aa__${1}}$2 \";;
esac"
}
## aunset STEM KEY
## Remove KEY from the associative array named STEM.
aunset () {
eval "unset __aa__${1}__${2}
case \$__aa__${1} in
*\" $2 \"*) __aa__${1}=\"\${__aa__${1}%%* $2 } \${__aa__${1}#* $2 }\";;
esac"
}
(Предупреждение, непроверенный код. Обнаружение ошибок для синтаксически неверных основ и ключей не предусмотрено.)