Zakładając, że chcesz ograniczyć do powłokach typu bourne (wiele innych muszli jak csh, tcsh, rc, eslub fishtablic wsparcia ale pisząc scenariusz zgodny jednocześnie do Bourne-jak muszle i tych jest trudne i na ogół pozbawione sensu, ponieważ są one tłumaczy na zupełnie inny i niekompatybilne języki), zauważ, że istnieją znaczące różnice między implementacjami.
Powłoki typu Bourne'a obsługujące tablice to:
ksh88(to pierwsza implementująca tablice, ksh88 jest nadal spotykany jak kshw większości tradycyjnych komercyjnych Unices, gdzie jest również podstawą sh)
- tablice są jednowymiarowe
- Tablice są zdefiniowane jako
set -A array foo barlub set -A array -- "$var" ...jeśli nie możesz zagwarantować, że $varnie rozpocznie się od znaku -lub +.
- Indeksy tablic zaczynają się od
0.
- Poszczególne elementy tablicy są przypisywane jako
a[1]=value.
- tablice są rzadkie. To
a[5]=foozadziała, nawet jeśli a[0,1,2,3,4]nie są ustawione i pozostawi je rozbrojone.
${a[5]}aby uzyskać dostęp do elementu indeksu 5 (niekoniecznie szóstego elementu, jeśli tablica jest rzadka). 5Nie może być dowolne wyrażenie arytmetyczne.
- Rozmiar tablicy i indeks dolny są ograniczone (do 4096).
${#a[@]} to liczba przypisanych elementów w tablicy (nie największy przypisany indeks).
- nie ma możliwości poznania listy przypisanych indeksów dolnych (oprócz testowania 4096 elementów indywidualnie
[[ -n "${a[i]+set}" ]]).
$ajest taki sam jak ${a[0]}. To znaczy, że tablice w jakiś sposób rozszerzają zmienne skalarne, nadając im dodatkowe wartości.
pdkshi pochodne (to podstawa, ksha czasem shkilka BSD i była jedyną implementacją ksh typu open source przed uwolnieniem źródła ksh93):
Najczęściej jak, ksh88ale uwaga:
- Niektóre stare implementacje nie obsługiwały
set -A array -- foo bar( --nie były tam potrzebne).
${#a[@]}to jeden plus wskaźnik największej przypisanej wartości. ( a[1000]=1; echo "${#a[@]}"wyprowadza 1001, mimo że tablica ma tylko jeden element.
- w nowszych wersjach rozmiar tablicy nie jest już ograniczony (inny niż rozmiar liczb całkowitych).
- Nowsze wersje
mkshmają kilka dodatkowych operatorów inspirowane z bash, ksh93lub zshpodobne zadania la a=(x y), a+=(z), ${!a[@]}aby uzyskać listę przypisanych indeksów.
zsh. zshtablice są na ogół lepiej zaprojektowane i podjąć najlepsze kshi cshtablice. Są podobne, kshale z istotnymi różnicami:
- indeksy zaczynają się od 1, a nie od 0 (z wyjątkiem
kshemulacji), co jest zgodne z tablicą Bourne'a (parametry pozycji $ @, która zshrównież wyświetla się jako tablica $ argv) i cshtablice.
- są one odrębnym typem od zmiennych normalnych / skalarnych. Operatorzy stosują się do nich inaczej i tak, jak zwykle można się spodziewać.
$anie jest tym samym co, ${a[0]}ale rozwija się do niepustych elementów tablicy ( "${a[@]}"dla wszystkich elementów jak w ksh).
- są to normalne tablice, a nie rzadkie tablice.
a[5]=1działa, ale przypisuje wszystkie elementy od 1 do 4 pusty ciąg, jeśli nie zostały one przypisane. Tak więc ${#a[@]}(to samo ${#a}co w ksh jest wielkością elementu indeksu 0) jest liczba elementów w tablicy i największy przypisany indeks.
- obsługiwane są tablice asocjacyjne.
- obsługiwana jest duża liczba operatorów do pracy z tablicami, zbyt duża, aby ją tutaj wymienić.
- tablice zdefiniowane jako
a=(x y). set -A a x ydziała również, ale set -A a -- x ynie jest obsługiwane, chyba że w emulacji ksh ( --nie jest potrzebne w emulacji zsh).
ksh93. (tutaj opisujące najnowsze wersje). ksh93, od dawna uważany za eksperymentalny można teraz znaleźć w coraz większej liczbie systemów, odkąd został wydany jako FOSS. Na przykład, jest to /bin/sh(gdzie zastąpiła Bourne Shell /usr/xpg4/bin/sh, POSIX powłoki nadal opiera się na ksh88) i kshod Solaris 11. Jego tablice rozszerzają i poprawiają ksh88.
a=(x y)może być użyty do zdefiniowania tablicy, ale ponieważ a=(...)jest również używany do zdefiniowania zmiennych złożonych ( a=(foo=bar bar=baz)), a=()jest niejednoznaczny i deklaruje zmienną złożoną, a nie tablicę.
- tablice są wielowymiarowe (
a=((0 1) (0 2))), a elementy tablicy mogą być również zmiennymi złożonymi ( a=((a b) (c=d d=f)); echo "${a[1].c}").
- Za pomocą
a=([2]=foo [5]=bar)składni można jednocześnie zdefiniować rzadkie tablice.
- Zniesiono ograniczenia wielkości.
- Nie w stopniu
zsh, ale ogromna liczba operatorów wsparła również manipulowanie tablicami.
"${!a[@]}" aby pobrać listę indeksów tablicowych.
- tablice asocjacyjne obsługiwane również jako osobny typ.
bash. bashjest powłoką projektu GNU. Jest używany jak shw najnowszych wersjach OS / X i niektórych dystrybucjach GNU / Linux. bashtablice najczęściej emulują ksh88te z niektórymi cechami ksh93i zsh.
a=(x y)utrzymany. set -A a x y nie obsługiwane a=()tworzy pustą tablicę (bez zmiennych złożonych bash).
"${!a[@]}" dla listy indeksów.
a=([foo]=bar)Składnia obsługiwane, a także kilka innych z ksh93i zsh.
- najnowsze
bashwersje obsługują również tablice asocjacyjne jako osobny typ.
yash. Jest to stosunkowo nowa, czysta, wielobajtowa implementacja sh POSIX. Nie w powszechnym użyciu. Jego tablice są kolejnym czystym API podobnym dozsh
- tablice nie są rzadkie
- Indeksy tablic zaczynają się od 1
- zdefiniowane (i zadeklarowane) za pomocą
a=(var value)
- Elementy wkładane, usuwane lub modyfikowane przy
arraypolecenie wbudowane
array -s a 5 valuemodyfikacja piątego elementu nie powiodłaby się, gdyby ten element nie został wcześniej przypisany.
- liczba elementów w matrycy
${a[#]}, ${#a[@]}jest wielkość elementów w formie listy.
- tablice są osobnym typem.
a=("$a")Przed dodaniem lub modyfikacją elementów należy ponownie zdefiniować zmienną skalarną jako tablicę.
- tablice nie są obsługiwane po wywołaniu jako
sh.
Z tego wynika, że wykrywanie obsługi macierzy jest możliwe dzięki:
if (unset a; set -A a a; eval "a=(a b)"; eval '[ -n "${a[1]}" ]'
) > /dev/null 2>&1
then
array_supported=true
else
array_supported=false
fi
nie wystarczy, aby móc korzystać z tych tablic. Musisz zdefiniować polecenia otoki, aby przypisać tablice jako całość i poszczególne elementy, i upewnij się, że nie próbujesz tworzyć rzadkich tablic.
Lubić
unset a
array_elements() { eval "REPLY=\"\${#$1[@]}\""; }
if (set -A a -- a) 2> /dev/null; then
set -A a -- a b
case ${a[0]}${a[1]} in
--) set_array() { eval "shift; set -A $1"' "$@"'; }
set_array_element() { eval "$1[1+(\$2)]=\$3"; }
first_indice=0;;
a) set_array() { eval "shift; set -A $1"' -- "$@"'; }
set_array_element() { eval "$1[1+(\$2)]=\$3"; }
first_indice=1;;
--a) set_array() { eval "shift; set -A $1"' "$@"'; }
set_array_element() { eval "$1[\$2]=\$3"; }
first_indice=0;;
ab) set_array() { eval "shift; set -A $1"' -- "$@"'; }
set_array_element() { eval "$1[\$2]=\$3"; }
first_indice=0;;
esac
elif (eval 'a[5]=x') 2> /dev/null; then
set_array() { eval "shift; $1=("'"$@")'; }
set_array_element() { eval "$1[\$2]=\$3"; }
first_indice=0
elif (eval 'a=(x) && array -s a 1 y && [ "${a[1]}" = y ]') 2> /dev/null; then
set_array() { eval "shift; $1=("'"$@")'; }
set_array_element() {
eval "
$1=(\${$1+\"\${$1[@]}"'"})
while [ "$(($2))" -ge "${'"$1"'[#]}" ]; do
array -i "$1" "$2" ""
done'
array -s -- "$1" "$((1+$2))" "$3"
}
array_elements() { eval "REPLY=\${$1[#]}"; }
first_indice=1
else
echo >&2 "Array not supported"
fi
A następnie uzyskać dostęp do elementów tablicy z "${a[$first_indice+n]}"cała lista ze "${a[@]}"i korzystać z funkcji otoki ( array_elements, set_array, set_array_element), aby uzyskać liczbę elementów tablicy (w $REPLY), ustawić tablicę jako całość lub przypisać poszczególnych elementów.
Prawdopodobnie nie warte wysiłku. Użyję perllub ograniczenie do tablicy powłoki Bourne'a / POSIX: "$@".
Jeśli intencją jest, aby jakiś plik był pozyskiwany przez interaktywną powłokę użytkownika w celu zdefiniowania funkcji, które wewnętrznie korzystają z tablic, oto kilka dodatkowych uwag, które mogą być przydatne.
Można skonfigurować zshtablice, aby były bardziej podobne do kshtablic w lokalnych zasięgach (w funkcjach lub funkcjach anonimowych).
myfunction() {
[ -z "$ZSH_VERSION" ] || setopt localoption ksharrays
# use arrays of indice 0 in this function
}
Możesz także emulować ksh(poprawić zgodność z kshtablicami i kilkoma innymi obszarami) z:
myfunction() {
[ -z "$ZSH_VERSION" ] || emulate -L ksh
# ksh code more likely to work here
}
Mając to na uwadze i jesteś gotów do spadku poparcia dla yasha ksh88i starsze wersje pdkshpochodne, i tak długo, jak nie próbować tworzyć macierze rzadkie, należy być w stanie konsekwentnie używać:
a[0]=foo
a=(foo bar)(ale nie a=())
"${a[#]}", "${a[@]}","${a[0]}"
w tych funkcjach, które mają emulate -L ksh, podczas gdy zshużytkownik nadal używa swoich tablic normalnie w sposób zsh.