Procházení řádků souboru: vysvětlení smyčky Bash For
Chci procházet řádky souboru pomocí skriptu Bash a jedním ze způsobů je použití smyčky for.
Co je to smyčka for?
Smyčka for je jednou z nejběžnějších programovacích konstrukcí a používá se k provedení daného bloku kódu vzhledem k sadě položek v seznamu. Řekněme například, že chcete napsat program, který vypíše počet lidí, kteří žijí v deseti největších evropských městech. Program může pomocí smyčky for projít každé město v seznamu a vypsat počet lidí pro dané město.
Prováděná logika je pokaždé stejná a jediné, co se mění, je město.
Níže vidíte obecnou syntaxi pro smyčku Bash for:
for item in do command1 command2 ... commandNdone
LIST může být například:
- rozsah čísel.
- posloupnost řetězců oddělených mezerami.
- výstup příkazu Linuxu (např. příkaz ls).
Pro každou položku seznamu se provede N příkazů mezi do a done.
Smyčka for v jazyce Bash
V tomto článku se naučíte používat smyčku for v jazyce Bash a konkrétně procházet řádky souboru.
Ale proč byste to dělali? Procházet řádky souboru?
Například to můžete potřebovat, pokud jste vyexportovali data z aplikace do souboru a chcete tato data nějak rozpracovat.
V tomto příkladu použijeme jednoduchý soubor .txt, ve kterém každý řádek obsahuje:
- jméno města
- počet lidí, kteří v tomto městě žijí.
Níže vidíte formát textového souboru, dvojtečka se používá k oddělení každého města od počtu lidí, kteří v daném městě žijí:
Istanbul:15,067,724Moscow:12,615,279London:9,126,366...
Jak tedy můžeme pomocí cyklu Bash for procházet obsah tohoto souboru?
Nejprve uložíme název souboru do proměnné
FILENAME="european-cities.txt"
Poté použijeme další proměnnou a příkaz cat, abychom získali všechny řádky souboru:
LINES=$(cat $FILENAME)
Zde použijeme nahrazení příkazu, abychom výstup příkazu cat přiřadili proměnným LINES.
Nakonec smyčka for umožňuje projít každý řádek souboru:
for LINE in $LINESdo echo "$LINE"done
Příkazy do a done slouží k definování příkazů, které se mají provést při každé iteraci smyčky for.
Příklad pokud máte soubor s 10 řádky, smyčka for projde 10 iterací a při každé iteraci přečte jeden řádek souboru.
Příkaz echo lze nahradit libovolnou posloupností příkazů podle toho, co chcete s jednotlivými řádky souboru provést.
Tady je výsledný skript:
#!/bin/bash FILENAME="european-cities.txt"LINES=$(cat $FILENAME)for LINE in $LINESdo echo "$LINE"done
A výstupem skriptu je…
./cities.sh Istanbul:15,067,724Moscow:12,615,279London:9,126,366Saint-Petersburg:5,383,890Berlin:3,748,148Kyiv:3,703,100Madrid:3,223,334Rome:2,857,321Paris:2,140,526Bucharest:2,106,144
Předáváme seznam do cyklu for pomocí příkazu cat.
To znamená, že můžeme použít libovolné příkazy, kterými vytvoříme seznam, který se předá do cyklu for.
Máte na mysli nějaké další možné příkazy?“
Smyčka for také není jedinou možností, jak vytvořit smyčku ve skriptu Bash, další možností je smyčka while.
Co je to čítač ve smyčce for v jazyce Bash?
V smyčce for můžete také definovat proměnnou s názvem čítač. Pomocí čítače můžete sledovat každou iteraci smyčky.
Používání čítače je velmi časté ve všech programovacích jazycích. Lze jej také použít pro přístup k prvkům datové struktury uvnitř cyklu (to není případ našeho příkladu).
Předchozí program upravíme a definujeme čítač, jehož hodnota se vypíše při každé iteraci:
#!/bin/bash FILENAME="european-cities.txt"LINES=$(cat $FILENAME)COUNTER=0for LINE in $LINESdo echo "Counter $COUNTER: $LINE" COUNTER=$((COUNTER+1))done
Jak vidíte, mimo cyklus for jsem definoval proměnnou s názvem COUNTER, jejíž počáteční hodnota je nastavena na nulu.
Poté při každé iteraci vypíšu hodnotu čítače spolu s řádkem ze souboru.
Poté použiji aritmetický operátor Bash, abych zvýšil hodnotu proměnné COUNTER o 1.
Poté vypisuji hodnotu proměnné COUNTER.
A zde je výstup skriptu:
Counter 0: Istanbul:15,067,724Counter 1: Moscow:12,615,279Counter 2: London:9,126,366Counter 3: Saint-Petersburg:5,383,890Counter 4: Berlin:3,748,148Counter 5: Kyiv:3,703,100Counter 6: Madrid:3,223,334Counter 7: Rome:2,857,321Counter 8: Paris:2,140,526Counter 9: Bucharest:2,106,144
Přerušení a pokračování ve smyčce for v jazyce Bash
Existují způsoby, jak změnit normální průběh smyčky for v jazyce Bash.
Dva příkazy, které to umožňují, jsou break a continue:
- break: přeruší provádění smyčky for a skočí na první řádek za smyčkou for.
- continue: skočí na další iteraci smyčky for.
Zdefinování čítače nám pomůže zjistit, co se stane, když do našeho stávajícího skriptu přidáme break nebo continue.
Začneme s break…
Přidám příkaz if na základě hodnoty čítače. Příkaz break uvnitř příkazu if přeruší provádění smyčky, pokud je čítač roven 3:
#!/bin/bash FILENAME="european-cities.txt"LINES=$(cat $FILENAME)COUNTER=0for LINE in $LINESdo if ; then break fi echo "Counter $COUNTER: $LINE" COUNTER=$((COUNTER+1))done
A výstup je:
Counter 0: Istanbul:15,067,724Counter 1: Moscow:12,615,279Counter 2: London:9,126,366
Jak vidíte, příkaz break zastaví provádění smyčky for před dosažením příkazu echo, protože hodnota COUNTER je 3.
Poté nahradíme break příkazem continue a uvidíme, co se stane. Zbytek kódu ponechám beze změny.
#!/bin/bash FILENAME="european-cities.txt"LINES=$(cat $FILENAME)COUNTER=0for LINE in $LINESdo if ; then continue fi echo "Counter $COUNTER: $LINE" COUNTER=$((COUNTER+1))done
A zde je výstup pro skript:
Counter 0: Istanbul:15,067,724Counter 1: Moscow:12,615,279Counter 2: London:9,126,366
Podivné… výstup je stejný. Proč?“
To proto, že když je hodnota COUNTER 3, příkaz continue skočí na další iteraci cyklu, ale nezvýší hodnotu čítače.
Takže při další iteraci je hodnota COUNTER stále 3 a příkaz continue se provede znovu, a tak dále pro všechny další iterace.
Chceme-li to napravit, musíme uvnitř příkazu if zvýšit hodnotu proměnné COUNTER:
#!/bin/bash FILENAME="european-cities.txt"LINES=$(cat $FILENAME)COUNTER=0for LINE in $LINESdo if ; then COUNTER=$((COUNTER+1)) continue fi echo "Counter $COUNTER: $LINE" COUNTER=$((COUNTER+1))done
Tentokrát vidíme správný výstup:
Counter 0: Istanbul:15,067,724Counter 1: Moscow:12,615,279Counter 2: London:9,126,366Counter 4: Berlin:3,748,148Counter 5: Kyiv:3,703,100Counter 6: Madrid:3,223,334Counter 7: Rome:2,857,321Counter 8: Paris:2,140,526Counter 9: Bucharest:2,106,144
Jak vidíte, v terminálu se nevypisuje „Counter 3: ….“.
Zapsání smyčky for na jednom řádku
Před ukončením tohoto tutoriálu se podíváme, jak můžeme zapsat smyčku for na jednom řádku.
Tento postup se nedoporučuje s ohledem na to, že váš kód je pak méně čitelný.
Je ale dobré vědět, jak zapsat smyčku na jednom řádku, dodá to vašim znalostem Bash větší hloubku.
Obecná syntaxe pro smyčku Bash for v jednom řádku je následující:
for i in ; do ; done
Vypíšeme obsah našeho textového souboru pomocí jednořádkové smyčky for:
#!/bin/bashFILENAME="european-cities.txt"LINES=$(cat $FILENAME)for LINE in $LINES; do echo $LINE; done
Pro zjednodušení jsem odstranil COUNTER a příkaz if. Kdyby tam byly, jednořádková smyčka for by byla mnohem hůře čitelná.
Snažte se vyhýbat jednořádkovým příkazům, pokud kvůli nim bude váš kód hůře čitelný.
Závěr
Na závěr tohoto tutoriálu jste se naučili:
- Ukládat řádky souboru do proměnné
- Procházet jednotlivé řádky pomocí smyčky for.
- Použít čítač v cyklu for.
- Změnit průběh cyklu pomocí break a continue.
- Napsat cyklus for na jeden řádek.
Dává to smysl?
Jak to hodláte použít?
Dejte mi vědět 🙂
Pokud se chcete dozvědět více o smyčkách ve skriptování Bash, podívejte se na tento tutoriál.
Související kurz ZDARMA: Kurz: Rozluštění skriptování Bash