Průvodce Bash Arrays

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.