Awk a příkazy - MujMAC.cz - Apple, Mac OS X, Apple iPod

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:

Soutěž

Sponzorem soutěže je:

IDIF

 

Kde se narodil známý fotograf František Drtikol?

V dnešní soutěži hrajeme o:

Seriály

Více seriálů



Informace

Awk a příkazy

21. února 2002, 00.00 | V našem postupném prokousávání se možnostmi příkazu awk jsme se konečně dostali k poslednímu z hlavních bloků — dnes se seznámíme s nejdůležitějšími příkazy, takže už budeme schopni využít téměř všechny možnosti příkazu awk

V našem postupném prokousávání se možnostmi příkazu awk jsme se konečně dostali k poslednímu z hlavních bloků — dnes se seznámíme s nejdůležitějšími příkazy, takže už budeme schopni využít téměř všechny možnosti příkazu awk (některé speciality, využívané jen zřídka, jsem vám pro zkrácení a zjednodušení "zatajil" — podrobně jsou samozřejmě popsány v man awk).

Výběr řádků

Nejprve jsme si slíbili malou odbočku k výběru řádků: od samého začátku umíme omezovat řádky pomocí regulárních výrazů, a brzy jsme se naučili používat také speciální specifikaci BEGIN a END.

V předcházejících dílech jsme se ale naučili konstruovat výrazy, obsahující relační testy (typu "$5<100000") a dokonce komplexní logické operátory (třeba "a<b && (c>=d || e!=f)"). Jistě by se občas hodilo mít možnost tyto výrazy používat pro výběr řádků; tvůrcům programu awk to naštěstí neušlo, takže tuto možnost skutečně máme.

Kompletní specifikace výběru řádků — tj. údajů, umístěných před otevírací složenou závorku, a určujících, kdy se příkazy uvnitř závorky použijí a kdy ne — tedy vypadá takto:

  • může zde stát již známé slovo BEGIN nebo END; příkazy se pak provedou před, respektive po zpracování všech řádků;
  • nebo zde může stát jeden výraz; příkazy se pak provedou pro každý řádek, pro který je výraz "pravdivý";
  • nebo dvojice výrazů, oddělených čárkou. Pak se příkazy provedou pro řádek, pro který je první výraz "pravdivý", a pro všechny řádky následující konče tím, pro který je "pravdivý" druhý výraz.

Kterýmkoli výrazem může být buďto regulární výraz, uzavřený mezi dvojici lomítek, nebo zcela obecný výraz zkonstruovaný s využitím proměnných, operátorů a funkcí, jež jsme si ukázali v minulých dílech. Regulární výraz je "pravdivý" jestliže odpovídá celému řádku; obecný výraz je "pravdivý" je-li jeho hodnota nenulová.

Pokud bychom tedy chtěli zpracovat třeba všechny řádky delší než sto znaků, použili bychom skript

length>100 { ... }

chceme-li z nějakého důvodu opsat na výstup každý řádek, který obsahuje "Holahej", a ještě dva řádky za ním, ať obsahují cokoli, mohli bychom použít třeba takovýto skript:

/Holahej/ {a=NR} a && NR<a+3

(Chybí vám na konci "{ print $0 }"? To je v pořádku, jde o malou službu pro pohodlí programátora, o níž jsme se dosud nezmínili: jestliže awk nenajde vůbec žádný příkaz pro zpracování vybraného řádku, prostě jej celý opíše na výstup.)

Malé cvičení: zkuste sestavit awk skript, který z libovolného vstupu opíše na výstup každý druhý řádek!

Příkazy

Ze všech příkazů, jimž awk rozumí, si popíšeme jen ty nejčastěji používané — to jsou příkazy pro řízení běhu programu (for, if a podobně), a příkaz delete.

Příkazy pro řízení běhu programu jsou velmi podobné příkazům jazyka C:

  • if (podmínka) then příkaz [ else příkaz2 ]: klasický příkaz if vyhodnotí podmínku; je-li pravdivá, provede příkaz. Je-li nepravdivá, provede příkaz2, je-li pomocí klíčového slova else zadán (jinak nedělá nic);
  • while (podmínka) příkaz: základní příkaz cyklu. Vyhodnotí se podmínka, a je-li pravdivá, provede se příkaz, a znovu dokola: vyhodnotí se podmínka...
  • for (inicializace;podmínka;iterace) příkaz: velmi flexibilní příkaz cyklu. Nejprve se provede inicializace; potom už příkaz for pracuje stejně jako příkaz while s podmínkou, přičemž před každým novým vyhodnocením podmínky se provede iterace. Podívejte se na jednoduchý příklad:

for (i=1;i<=10;i++) print i;

nejprve nastaví proměnnou "i" na jedničku (inicializace). Cyklus probíhá tak dlouho, dokud je obsah proměnné "i" menší nebo roven deseti (podmínka). Před každým dalším provedením cyklu se k "i" přičte jednička (iterace). V praxi to prostě znamená, že se vypíší čísla od jedné do deseti...

  • for (proměnná in pole) příkaz: příkaz se provede pro všechny prvky pole; pokaždé je do proměnné uložen odpovídající index. Připomeňme, že indexy mohou být libovolné textové řetězce;
  • { ... }: libovolné množství příkazů uložených mezi dvojici složených závorek může stát v příkazech if, while nebo for na místě jejich příkazu;
  • break: jestliže v průběhu zpracovávání cyklu (příkazu while nebo for) dojde ke zpracování příkazu break, cyklus se okamžitě ukončí. To je šikovné pro případy, kdy chceme podmínku vyhodnotit až v průběhu zpracování cyklu. Dejme tomu, že procházíme nějaké pole, a chceme skončit narazíme-li na zápornou hodnotu:

for (i in pole) {
  print i,pole[i]
  if (pole[i]<0) break;
  ... další zpracování ...
}

Samozřejmě, že jako příkaz můžeme použít také libovolný výraz; typicky takto používáme přiřazovací výrazy ("a=5; b+=13") nebo příkazy pro přičtení / odečtení jedničky ("c++; d--").

Speciální příkaz delete umožňuje zrušit hodnotu, jež byla uložena do pole: jeho argumentem může být jméno pole a požadovaný index, nebo jen jméno pole; v tom případě se zruší všechny jeho prvky:

270 /tmp> awk 'BEGIN {
quote> for (i=0;i<10;i++) a[i]="Hodnota " i
quote> for (i in a) print i,"=",a[i]
quote> delete a[1]; delete a[4]; delete a[5];
quote> print "Po zruseni"
quote> for (i in a) print i,"=",a[i]
quote> delete a
quote> print "Po zruseni vseho je v a prazdno:"
quote> for (i in a) print i,"=",a[i]
quote> print "Konec"
quote> }'
2 = Hodnota 2
3 = Hodnota 3
4 = Hodnota 4
5 = Hodnota 5
6 = Hodnota 6
7 = Hodnota 7
8 = Hodnota 8
9 = Hodnota 9
0 = Hodnota 0
1 = Hodnota 1
Po zruseni
2 = Hodnota 2
3 = Hodnota 3
6 = Hodnota 6
7 = Hodnota 7
8 = Hodnota 8
9 = Hodnota 9
0 = Hodnota 0
Po zruseni vseho je v a prazdno:
Konec
271 /tmp> 

To je vlastně všechno

Základní možnosti příkazu awk už známe. Samozřejmě, že awk toho umí mnohem víc: můžeme pracovat s různými soubory pomocí funkce getline; funkce printf umožní formátovat výpisy přesně podle našich požadavků... Tyto speciality však jsou zapotřebí poměrně zřídkakdy.

A cvičení z odstavce "Výběr řádků"? Jistě to každý zvládl sám; jen pro jistotu, odpovídající skript samozřejmě vypadá takto: NR%2. Nic víc není zapotřebí...

Příště se opět od shellu a jeho příkazů vrátíme k úplným základům unixového prostředí, a začneme si povídat o vlastnictví a přístupových právech: to je vlastně už poslední z opravdu základních věcí, již zatím neznáme...

Obsah seriálu (více o seriálu):

Tématické zařazení:

 » Rubriky  » Informace  

 » Rubriky  » Agregator  

 » Rubriky  » Software  

 

 

 

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: