Tento návod vás seznámí s principy deklarace a manipulace s indexovanými a asociativními poli v Bash.
V prostředí Bash máte možnost vytvářet pole pro uchování kolekcí prvků. Tato pole jsou jednorozměrná. V programovacích jazycích, jako je C a C++, jsou pole soubory prvků identického datového typu. Nicméně, v Bash můžete, podle potřeby, v jednom poli kombinovat celá čísla a textové řetězce.
V tomto tutoriálu se naučíte, jak definovat pole v Bash a jak přistupovat k jejich jednotlivým položkám. Dále se seznámíte s postupy iterace přes pole a přidávání nových elementů. Závěrem prozkoumáme možnosti asociativních polí v Bash.
Začněme!
⚙ Máte chuť kódovat? Zde jsou základní požadavky:
Deklarace polí v Bash
V této kapitole se seznámíte se syntaxí pro vytváření polí v Bash, doplněnou o praktické ukázky.
Základní syntaxe pro deklaraci pole
Pole v Bash definujete pomocí tohoto formátu:
$ nazevPole=(prvek1 prvek2 ... prvekN) # nazevPole je název pole # prvek1 až prvekN představují N prvků v poli
V uvedeném zápisu „nazevPole“ reprezentuje název, který jste vybrali pro své pole, a obsahuje N prvků označených jako „prvek1“ až „prvekN“.
Jednotlivé prvky pole jsou vloženy mezi kulaté závorky (). Důležité je, že prvky jsou od sebe odděleny mezerou. Stejně jako u všech proměnných v Bash, před a za operátorem přiřazení = se nesmí nacházet mezery.
📑 V mnoha programovacích jazycích se pro oddělování prvků pole nebo podobných datových struktur používá čárka. Nicméně, v Bash je separátorem mezera.
V Bash se pole, kde jsou prvky identifikovány pomocí indexu, označují jako indexovaná pole.
Praktická ukázka indexovaných polí v Bash
Vytvořme si pole čísel, které budeme nazývat „ceny“.
$ ceny=(24 27 18 30 15)
Jak je vidět v syntaxi, čísla v poli „ceny“ jsou oddělena mezerami a uzavřena v závorkách bez mezer před a za operátorem =.
Pro zobrazení obsahu proměnné se v Bash používá příkaz „echo“. Zápis „$nazevPromenne“ vypíše hodnotu dané proměnné. Pokud ale použijete pouze název pole, zobrazí se pouze jeho první prvek.
$ echo $ceny 24
Pole v Bash jsou indexována od nuly. To znamená, že první prvek má index 0, druhý prvek index 1 a tak dále. Můžete použít i záporné indexování, kde index posledního prvku pole je -1.
Co se stane, když se pokusíte získat prvek s konkrétním indexem a pokusíte se ho vypsat? Zkusme vypsat prvek s indexem 1.
$ echo $ceny[1] 24[1]
Proč se zobrazil výstup 24[1]? 🤔 Je to proto, že Bash nahradí „$ceny“ hodnotou 24, což je první prvek pole, a „[1]“ se vypíše doslova.
Pro vypsání prvku na konkrétním indexu je nutné použít rozšíření parametru ve formátu ${ceny[index]}.
$ echo ${ceny[1]} # 27 $ echo ${ceny[2]} # 18
Pro výpis všech prvků pole je třeba namísto konkrétního indexu použít symbol „@“.
$ echo ${ceny[@]} 24 27 18 30 15
Nyní si ukážeme, jak vytvořit pole řetězců. Následujícím příkazem vytvoříme indexované pole:
$ declare -a ovoce
Volba „-a“ zajistí, že se vytvoří indexované pole. Nyní můžete pole naplnit prvky jeden po druhém, zadáváním hodnot na konkrétních indexech, jak je uvedeno níže:
$ ovoce[0]="třešeň" $ ovoce[1]="jahoda" $ ovoce[2]="jablko" $ ovoce[3]="hruška" $ ovoce[4]="meloun" $ ovoce[5]="pomeranč"
Pro zobrazení všech prvků v poli použijeme ${ovoce[@]}.
$ echo ${ovoce[@]} třešeň jahoda jablko hruška meloun pomeranč
Přístup k prvkům polí v Bash
K prvkům pole lze přistupovat různými způsoby:
- Procházením pole a přímým přístupem k prvkům
- Iterací přes sadu indexů a přístupem k prvkům na daných indexech
Procházení pole a přístup k prvkům
Pokud máte zkušenosti s Pythonem, znáte smyčku for ve formátu:
for prvek in seznam: print(prvek)
Nyní si ukážeme, jak zapsat ekvivalentní smyčku v Bash.
Již víme, že ${ceny[@]} se rozvine do všech prvků pole „ceny“ a že tento zápis nám poskytne jejich hodnoty.
Smyčka for v Bash je podobná té z Pythonu, ale příkazy uvnitř smyčky musí být uzavřeny mezi klíčová slova „do“ a „done“, jak ukazuje příklad:
$ for cena in ${ceny[@]} > do > echo $cena > done
Použijeme-li příkaz „echo“ a vypíšeme proměnnou „cena“, dostaneme následující výstup:
# výstup 24 27 18 30 15
Přístup k prvkům pomocí indexu
Dalším způsobem, jak procházet polem, je využití indexů prvků. Tato metoda je podobná použití funkce „range()“ v Pythonu:
for i in range(len(seznam)): print(i)
Chcete-li získat seznam indexů pro iteraci, použijte vykřičník „!“ před názvem pole v rozšíření parametru. Tím získáte seznam všech platných indexů pro dané pole:
$ echo ${!ceny[@]} 0 1 2 3 4
Pole „ceny“ obsahuje 5 prvků, proto indexy začínají na 0 a končí na 4.
Nyní můžeme procházet seznam indexů a přistupovat k prvku na každém indexu. Pro index „i“ je ${ceny[i]} prvek na indexu „i“.
$ for i in ${!ceny[@]} > do > echo ${ceny[i]} > done
Výše uvedená smyčka vypíše všechny prvky v poli.
# výstup 24 27 18 30 15
💬 V tomto případě jsme provedli jednoduchou operaci vypsání hodnoty každého prvku. Obecně však můžeme s prvky provádět jakékoli validní operace.
Přidávání prvků do pole v Bash
Pole „ceny“ aktuálně obsahuje pět prvků (s indexy 0, 1, 2, 3 a 4). Pokud chceme přidat prvek na konec pole, na index 5, můžeme to udělat takto:
$ ceny[5]=21
Vidíme, že hodnota 21 byla přidána na konec pole „ceny“.
$ echo ${ceny[@]} 24 27 18 30 15 21
Je ale pohodlnější přidávat prvky na konec pole, aniž bychom museli pamatovat na index posledního přidaného prvku, nebo na celkový počet prvků v poli.
Pro připojení jednoho nebo více prvků na konec pole použijeme formát „nazevPole+=(prvky)“.
$ ceny+=(10)
Po vypsání pole „ceny“ uvidíme, že na jeho konec byla přidána hodnota 10.
$ echo ${ceny[@]} 24 27 18 30 15 21 10
Nyní se podíváme na to, jak deklarovat asociativní pole v Bash.
Asociativní pole v Bash
Pokud potřebujete definovat vztah mezi páry klíč–hodnota, můžete využít asociativní pole. Asociativní pole se deklarují pomocí následující obecné syntaxe. Důležité je, že namísto „-a“ se zde používá volba „-A“.
$ declare -A ovoce_ceny
Prvky do asociativního pole přidáváme zadáním klíče a odpovídající hodnoty. V našem případě přidáme názvy ovoce jako klíče a čísla z pole „ceny“ jako hodnoty.
$ ovoce_ceny[třešeň]=24 $ ovoce_ceny[jahoda]=27 $ ovoce_ceny[jablko]=18 $ ovoce_ceny[hruška]=30 $ ovoce_ceny[meloun]=15 $ ovoce_ceny[pomeranč]=21
Jak se tedy přistupuje k prvkům asociativního pole?
Podobně jako se v Pythonu vyhledává hodnota pomocí odpovídajícího klíče ve slovníku, i v asociativním poli v Bash můžeme přistupovat k hodnotám pomocí klíčů.
$ echo ${ovoce_ceny[jahoda]} # 27
Vidíme, že ${ovoce_ceny[@]} se rozvine do hodnot a ${!ovoce_ceny[@]} se rozvine do klíčů.
$ echo ${ovoce_ceny[@]} # Výstup: 18 27 21 24 30 15 $ echo ${!ovoce_ceny[@]} # Výstup: jablko jahoda pomeranč třešeň hruška meloun
Poznámka: Pořadí prvků není totožné s pořadím, ve kterém byly do pole přidány. Důvodem je, že na rozdíl od indexovaných polí nejsou asociativní pole uspořádané kolekce. Fungují na principu asociace mezi klíči a hodnotami. Klíče v asociativních polích tedy plní stejnou roli jako indexy v indexovaných polích.
Můžeme také iterovat přes asociativní pole a přistupovat ke klíčům, jak je ukázáno níže:
$ for klíč in ${!ovoce_ceny[@]} > do > echo $klíč > done
# Výstup jablko jahoda pomeranč třešeň hruška meloun
Následující smyčka ukazuje, jak přistupovat k hodnotám.
$ for hodnota in ${ovoce_ceny[@]} > do > echo $hodnota > done
# Výstup 18 27 21 24 30 15
I když se pro deklaraci asociativního pole doporučuje používat formát „nazevPole[klíč]=hodnota“, je možné definovat pole jako sekvenci klíč–hodnota:
declare -A nazevPole nazevPole=(klíč1 hodnota1 klíč2 hodnota2 ... klíčN hodnotaN)
V tomto formátu Bash automaticky interpretuje první prvek jako první klíč, druhý prvek jako první hodnotu a tak dále.
Shrnutí
Doufám, že nyní lépe rozumíte tomu, jak vytvářet a pracovat s poli v Bash. Zde je rychlý přehled toho, co jste se naučili:
- Indexované pole v Bash deklarujete pomocí syntaxe „nazev_pole=(prvek1 prvek2 prvek3 … prvekN)“ nebo příkazem „declare -a nazev_pole“, po kterém následuje přidávání prvků.
- Pro přístup k prvkům pole můžete použít zápis ${nazevPole[@]}. Alternativně můžete získat seznam všech platných indexů pomocí ${!nazevPole[@]}.
- Také jsme si ukázali, jak deklarovat asociativní pole pro ukládání párů klíč–hodnota v Bash.
Dále se podívejte na tutoriál o smyčkách v Bash.