Viděl jsem trik pro implementaci asociativních polí ve skriptu shellu. Například print array["apples"]
může být napsáno jako echo $array$key
kde klíč=jablka.
Nebyla zde však žádná zmínka o tom, jak generovat klíče pro iteraci přes pole.
Jediný způsob, jak mě napadl, bylo uložit klíče do proměnné oddělené mezerami, abych mohl k iteraci použít smyčku for přes pole.
Existuje tedy nějaký jiný způsob, jak uložit klíče pro pozdější použití?
Přijatá odpověď:
Skořápky s asociativními poli
Některé moderní shelly poskytují asociativní pole:ksh93, bash ≥4, zsh. V ksh93 a bash, pokud a
je asociativní pole, pak "${!a[@]}"
je pole jeho klíčů:
for k in "${!a[@]}"; do
echo "$k -> ${a[$k]}"
done
V zsh tato syntaxe funguje pouze v režimu emulace ksh. Jinak musíte použít nativní syntaxi zsh:
for k in "${(@k)a}"; do
echo "$k -> $a[$k]"
done
${(k)a}
funguje také, pokud a
nemá prázdný klíč.
V zsh můžete také zacyklit na obou k
eys a v
alues ve stejnou dobu:
for k v ("${(@kv)a}") echo "$k -> $v"
Skořápky bez asociativních polí
Emulovat asociativní pole v shellech, které je nemají, je mnohem pracnější. Pokud potřebujete asociativní pole, je pravděpodobně čas přinést větší nástroj, jako je ksh93 nebo Perl.
Pokud potřebujete asociativní pole v pouhém prostředí POSIX, zde je způsob, jak je simulovat, když klíče mohou obsahovat pouze znaky 0-9A-Z_a-z
(číslice ASCII, písmena a podtržítko). Za tohoto předpokladu mohou být klíče použity jako součást názvů proměnných. Níže uvedené funkce působí na pole identifikované předponou názvu, „kmenem“, které nesmí obsahovat dvě po sobě jdoucí podtržítka.
## 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"
}
(Varování, netestovaný kód. Detekce chyb pro syntakticky neplatné kmeny a klíče není k dispozici.)
Související:Linux – pomalá média – ladění mezipaměti disku?