Pociski z tablicami asocjacyjnymi
Niektóre nowoczesne powłoki zapewniają tablice asocjacyjne: ksh93, bash ≥4, zsh. W ksh93 i bash, jeśli a
jest tablicą asocjacyjną, "${!a[@]}"
to tablica jej kluczy:
for k in "${!a[@]}"; do
echo "$k -> ${a[$k]}"
done
W zsh ta składnia działa tylko w trybie emulacji ksh. W przeciwnym razie musisz użyć natywnej składni zsh:
for k in "${(@k)a}"; do
echo "$k -> $a[$k]"
done
${(k)a}
działa również, jeśli a
nie ma pustego klucza.
W Zsh możesz także zapętlać jednocześnie k
eys i v
alue:
for k v ("${(@kv)a}") echo "$k -> $v"
Pociski bez tablic asocjacyjnych
Emulowanie tablic asocjacyjnych w powłokach, które ich nie mają, to dużo więcej pracy. Jeśli potrzebujesz tablic asocjacyjnych, prawdopodobnie czas wprowadzić większe narzędzie, takie jak ksh93 lub Perl.
Jeśli potrzebujesz tablic asocjacyjnych w zwykłej powłoce POSIX, oto sposób ich symulacji, gdy klucze są ograniczone tylko do znaków 0-9A-Z_a-z
(cyfry ASCII, litery i podkreślniki). Przy takim założeniu klucze mogą być używane jako część nazw zmiennych. Poniższe funkcje działają na tablicę identyfikowaną przez przedrostek nazewnictwa „rdzeń”, który nie może zawierać dwóch kolejnych znaków podkreślenia.
## 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"
}
(Ostrzeżenie, nieprzetestowany kod. Wykrywanie błędów dla składniowo niepoprawnych rdzeni i kluczy nie jest zapewnione).