A Bash kétféle paramétert ismer: „skalár” értékeket és tömböket. A skalár érték lehet string vagy szám; egyetlen „dolgot” képvisel.
A legtöbbször elegendő skalár értékekben tárolni az adataidat. Néha azonban skalár értékek listáját kell eltárolnod. Ilyenkor tömböt használsz.
Kétféle tömb létezik:
A dokumentum első néhány szakasza a numerikusan indexelt tömbökkel foglalkozik (a továbbiakban egyszerűen „tömbök”). Az asszociatív tömbök részletei a végén kerülnek elő.
A Bash tömbjei kizárólag skalár értékeket tárolhatnak. Kétdimenziós tömböt (tömbök tömbjét) nem lehet létrehozni.
Egy tömböt úgy inicializálhatsz, hogy zárójelbe tett elemek listáját (ami akár üres is lehet) rendelsz egy változóhoz.
myarray=("one" "two" "three")
Ahogy minden értékadásnál, itt sem lehet szóköz az egyenlőségjel körül.
Figyeld meg, hogy az elemek között nincsenek vesszők; a lista stringekből áll, amelyeket szóköz választ el.
Valójában a zárójelek közötti szóközök mennyisége teljesen tetszőleges. Sortöréseket is használhatsz; annyit írj, amennyivel átláthatóbb lesz a kód.
myarray=(
"first element"
"second element"
"this is the last element"
)
Ha így rendelsz stringek listáját egy tömbváltozóhoz, az első string a 0. indexre kerül, a következő az 1. indexre, az azután következő a 2. indexre, és így tovább.
Egy „ritka tömböt” is inicializálhatsz úgy, hogy megadod a szükséges indexeket.
raindrops=([3]="Pling" [5]="Plang" [7]="Plong")
Hogy még egyszer leszögezzük: a tömbök indexelése nullától indul. Az alábbi részlet „true”-t ír ki:
myarray=("one" "two" "three")
[[ "${myarray[0]}" == "one" ]] && echo true || echo false
A declare (vagy függvényen belül a local) paranccsal megadhatod, hogy egy változó tömböt fog tartalmazni.
declare -a myarray
Sokkal idiomatikusabb egyszerűen egy (esetleg üres) zárójeles listát rendelni a változóhoz, és így inicializálni azt.
Ahogy a fenti megjegyzésben láttad, egy tömbelem elérésének szintaxisa ${myarray[$index]}.
Az indexet szögletes zárójelben adod meg.
A kapcsos zárójelek kötelezők.
Numerikusan indexelt tömböknél az index egy aritmetikai kifejezés. A Bash kézikönyve ezt írja:
Egy aritmetikai kifejezésen belül a shellváltozókra név szerint is hivatkozhatsz, anélkül hogy a paraméterkiterjesztés szintaxisát használnád.
Ez azt jelenti, hogy „egyszerű” változókiterjesztésnél a $ nem kötelező.
Az elemeket így is elérheted, ami egy kicsit olvashatóbb:
i=5
echo "${myarray[i]}"
# ..............^
Ha a megadott index nem létezik a tömbben, a kiterjesztés eredménye egy üres string.
Egy adott tömbelemhez így rendelhetsz értéket:
myarray[10]="hello"
Ha hozzá akarsz fűzni a tömbhöz, használd a += összefűző értékadás operátort, és tedd zárójelbe az elemeket:
myarray+=("new element 1" "new element 2")
Általában egy tömb értékei fölött kell iterálnod. Használj egy for ciklust (amit a ciklusok fogalomnál láttál):
myarray=("one" "two" "three")
for value in "${myarray[@]}"; do
echo "$value"
done
Figyeld meg a tömb kiterjesztésének speciális szintaxisát: "${myarray[@]}"
A paraméterkiterjesztésnek ez a formája külön szavakként helyettesíti be a tömb értékeit.
Nagyjából ez felel meg a következőnek:
for value in "${myarray[0]}" "${myarray[1]}" ... "${myarray[n]}"
A "${myarray[@]}" forma ritka tömbökkel is működik, és csak a definiált értékekre terjed ki.
Ez a speciális kiterjesztés, ahol az index egy kukac (@), csak kettős idézőjelek között speciális.
Íme még néhány speciális szintaxis, amelyre a tömbön való iteráláshoz szükségünk van. Ezeket a kézikönyv a shell paraméterkiterjesztésről szóló részében írja le.
Egy tömb hosszát a ${#myarray[@]} kifejezéssel kapod meg, a név elé írt # jellel.
Egy tömb „hossza” a benne lévő elemek számát jelenti.
Egy tömb indexeinek listáját a "${!myarray[@]}" kifejezéssel kapod meg, a név elé írt ! jellel és a kiterjesztéssel kettős idézőjelekben.
Numerikusan indexelt tömböknél az indexek növekvő számsorrendben jelennek meg.
Néha az érték mellett az indexre is szükséged van. Erre többféle módszer létezik.
Ha tudod, hogy az indexek megszakítás nélküli sorozatot alkotnak, használhatsz aritmetikai for ciklust.
for ((i = 0; i < ${#myarray[@]}; i++)); do
echo "$i -> ${myarray[i]}"
done
Figyeld meg a ${#myarray[@]} szintaxist, a # karakterrel a tömb neve előtt.
Mivel a tömbök indexelése nullától indul, a tömb utolsó indexe eggyel kevesebb a tömb hosszánál.
Ha a tömb ritka, ezt a formát használhatod:
for index in "${!raindrops[@]}"; do
echo "$index -> ${raindrops[index]}"
done
Figyeld meg a ${!myarray[@]} szintaxist, a ! karakterrel a tömb neve előtt.
Ha meg szeretnéd nézni egy tömb tartalmát, használd a declare parancsot a -p kapcsolóval:
a=("the 'first' element"
second
third
'the "last" element')
declare -p a
Ez a tartalmat a shell kanonikus idézőjelhasználatával írja ki.
declare -a a=([0]="the 'first' element" [1]="second" [2]="third" [3]="the \"last\" element")
Hogy ismételjük: az asszociatív tömbök indexként stringeket használnak, nem számokat. Minden, ami fentebb le van írva, az asszociatív tömbökre is érvényes, csak apró különbségekkel. Általában kulcsról beszélünk, nem indexről: az asszociatív tömbök kulcsokat rendelnek értékekhez.
A tömbökkel ellentétben az asszociatív tömböket deklarálni kell.
Az asszociatív tömböket a declare -A kapcsolójával deklarálhatod (függvényen belül ugyanígy a local paranccsal):
declare -A mymap
myfunc() {
local -A my_local_map
# ...
}
A kulcs-érték párokat a zárójeles listán belül adod meg:
mymap=([first]=foo [second]=bar [third]=baz)
declare -p mymap
Ez a következőt írja ki:
declare -A mymap=([second]="bar" [first]="foo" [third]="baz")
Tartsd észben, hogy az asszociatív tömbök rendezetlenek.
A deklaráció és az inicializálás történhet egy sorban.
declare -A mymap=([first]=foo [second]=bar [third]=baz)
Az újabb Bash-verziókban az inicializáláshoz használhatsz (key value key value ...) listát is.
declare -A mymap=(first foo second bar third baz)
Az elemek eléréséhez ugyanazt a szintaxist használod, mint korábban: ${mymap[$key]}.
Az asszociatív tömbök kulcsait nem aritmetikai kontextusban értékeli ki a shell. A szokásos paraméterkiterjesztés szintaxisára van szükség.
Az értékadás ugyanazt a szintaxist használja, mint korábban:
mymap[$key]="$value"
Iterálhatsz egy for value in "${mymap[@]}" ciklussal.
Azonban általában a kulcsra is szükséged van az érték mellett.
Használd a fentebb látott "${!mymap[@]}" szintaxist.
for key in "${!mymap[@]}"; do
echo "$key -> ${mymap[$key]}"
done
Ez a következőt írja ki:
second -> bar
first -> foo
third -> baz
Hangsúlyozzuk még egyszer: a kulcsoknak nincs meghatározott sorrendjük.