ADE: GNU Awk 2.15Jan Skýpala
Patříte-li mezi běžné počítačové uživatele, asi byste občas docela rádi
provedli nějaké úpravy některých textových souborů, jejichž obsah má určitou
formu, případně extrahovali data z takových souborů. Napsat program pro tuto
činnost v Céčku nebo Pascalu může být docela zbytečnou ztrátou času - v jiných
jazycích to může být řádově snazší. Jednou z možností na Amize je Arexx. Jinou
je prográmek gawk - interpret jazyka awk specializovaného na zpracování textu.
Základní funkcí gawk je vyhledávání řádek textu, které odpovídají danému vzoru.
Když je nalezena řádka, na kterou daný vzor sedí, lze nad ní provést nějakou
akci. Při spuštění gawku specifikujete program, který je ve formátu VZOR {AKCE}
VZOR{AKCE}
... Uveďme si jednoduchý příklad. Máte například seznam internetovských
konferencí a chcete vypsat všechny ty, v kterých se vyskytuje slovo amiga.
Spustíte tedy gawk „/amiga/ { prim $0 }“ maillists Když je v souboru maillists nalezena řádka, na které se nachází slovo amiga,
gawk tuto řádku vytiskne (protože příkaz print $0 přesně to znamená). Slovo
amiga je uzavřeno v lomítkách, které označují, že amiga je vzor, který se má
hledat. Celý program je uzavřen do uvozovek, aby byl předán gawku jako jeden
argument.
V programu může být buď vzor anebo akce vypuštěna. Pokud je vypuštěn vzor, bude
akce provedena na každý řádek textu. Jestliže je vypuštěna akce, pak se provede
základní akce - řádek odpovídající vzoru bude vytisknut. To znamená, že ve výše
zmíněném příkladu mohl být příkaz print $0 vynechán. Pokud by však byly
ponechány složené závorky, jednalo by se o prázdný příkaz nebyla by provedena
žádná akce.
Za první dvojici vzor-akce lze uvést další. Např. gawk „/amiga/ { print $0 } /linux/ { print $0 }“ maillists vypíše všechny konference, které mají ve jménu amiga nebo linux. Pozor, gawk
se na každý řádek postupně pokouší aplikovat všechny vzory - ať porovnání s
předchozími vzory byla úspěšná nebo ne. Pokud pro daný řádek vzor sedí, je
provedena akce. To znamená, že řádky textu, na nichž bude napsáno jak amiga tak
linux, budou vytištěny dvakrát! Abychom tomuto zabránili, spojíme vzory: gawk „/amiga/ || /linux/ { prim $0 }“ maillists Zde jsme mezi vzory dali operátor logického nebo. Podobně lze použít operátor
logického a zároveň (&&), případně negaci (!) a do výrazů dle potřeby přidávat
závorky. Takto jsme udělali nebo mezi dvěma vzory, nebo lze však provést i v
rámci vzoru. Pak bude řádek vypadat takto: gawk „/amiga|linux/ { prim $0 }“ maillists Zatímco mezi vzory lze provádět jen jednoduché logické porovnání (i to se
však může hodit a existují další operátory, viz níže), přímo v rámci vzoru lze
definovat mnoho různých podmínek. Např. prvním způsobem šlo zajistit, aby se
jednalo o řádek, na kterém se vyskytují slova amiga a program, ale nebylo možné
vyžadovat, aby tato slova byla v tomto pořadí. Vzor je však regulárním výrazem a
pomocí něj to zajistit lze (/amiga.*program/). Význam jednotlivých symbolů v
regulárním výrazu je takovýto:
. (tečka) označuje libovolný znak (kromě ASCII 10 = nový řádek)
^ vyžaduje začátek řádku (/^amiga/ odpovídá jen těm řádkům, které začínají
slovem amiga)
$ označuje konec řádku
[...] je výčet možných znaků; např. [ABC] znamená jeden znak, a to buď A nebo B
nebo C; výčet je možné definovat intervalem, např. [0-9] znamená libovolnou
číslici
[^...] je vše kromě uvedených znaků. [^0-9] označuje cokoliv kromě číslice.
| je logické nebo. ABC|[0-9] označuje bud ABC nebo číslici
(...) závorkami lze ovlivňovat vyhodnocování výrazu
* hvězdička označuje libovolný (i nulový) výskyt předchozího znaku, případně
uzávorkovaného podvýrazu; ph*x znamená p, které může být následované libovolným
(i nulovým) počtem znaku h a za nimi musí být bezpodmínečně znak x
+ plus má podobnou funkci jako hvězdička, ale musí se jednat alespoň o jeden
výskyt. To znamená, že ph+x je totéž jako phh*x
? otazník označuje jeden nebo žádný výskyt. Takže ph?x odpovídá buď px nebo phx
obrácené lomítko umožňuje specifikovat výskyt znaku, který je rezervován pro
nějakou funkci ve vzoru. Například $ bude označovat skutečný výskyt znaku
string a ne konec řádku.
Standardní porovnávání řetězce je u gawku case-sensitive (velká písmena jsou
různá od malých). Pokud je zapotřebí porovnávat řetězce bez ohledu na velikost
písmen, je bud možné použít výčtu ([Ww] bude odpovídat jak velkému tak malému
dvojitému vé), to však je u delších textů pracné, a tak je možné nastavit
proměnnou IGNORECASE na jinou hodnotu než 0 (např. IGNORECASE=1).
Někdy je zapotřebí specifikovat jenom pevnou část řetězce, kterou chceme
testovat na výskyt nějakého vzoru. Chytří čtenáři již možná odhadli, že $0
označuje celý řádek. $1 pak označuje první slovo, $2 druhé atd. Máte-li
nainstalovaný pdksh shell z ADE distribuce (anebo sedíte někde na Unixu), příkaz ls –l | gawk „$6 ~ /Oct/“ vypíše všechny soubory, které byly modifikovány v říjnu. Pozor, v Unixových
shellech musíte místo do uvozovek program uzavírat do apostrofů. Znak vlnovka je
operátorem „odpovídá“, dvojznak !~ je operátorem „neodpovídá“, tj. je čímkoliv
jiným než.
Nyní se již dostáváme k možnosti velmi mocného použití gawku. Např. následovně
lze zajistit smazání všech souborů - ale ne adresářů - modifikovaných v lednu: rm -f ls -l | gawk ($1 !~ /^d/) && ($6 ~ /Jan/) {print $9} ($1 !~ /^d/) zajistí vypuštění všech adresářů (příkaz ls vypisuje jako první
slovo atributy souboru, přičemž u adresářů je prvním atributem písmeno d).
{print $9} zajistí výpis jména souboru (ls ho vypisuje jako deváté slovo) a
obrácené apostrofy zajistí převedení výstupu gawku na parametry pro příkaz rm.
Jsou-li porovnávané řetězce čísly, lze s nimi jako s čísly pracovat. Např. ($5 >
1024) zajistí vybrání těch řádků, u nichž je číslo, které je pátým slovem na
řádku, větší než 1024. Množina použitelných operátorů je velká, kromě
porovnávacích lze použít třeba i aritmetické např. ($4 * $5 <= $6).
Dále lze v gawk pracovat i s proměnnými. Ty není potřeba definovat předem, jsou
zadefinovány svým prvním výskytem. Pokud je s proměnnou pracováno jako s číslem,
bude mít počáteční hodnotu nula, jinak se bude jednat o prázdný řetězec. Takto
lze například vypsat součet délek všech souborů na disku, jejichž vlastníkem je
DrNo pomocí ls -l | gawk $3 == „DrNo“ {sum += $5} END {prim sum} Pro každý soubor, jehož vlastníkem je DrNo bude k proměnné sum přičten obsah
pátého pole (do něhož ls -l vypisuje délku souboru). Podmínka END bude splněna
po projdení celého souboru - v ten moment bude vypsána celková délka. Podobně
jako END existuje i podmínka BEGIN.
Gawk je velmi mocným nástrojem pro jednoduché zpracování textu. Umí mnohem více,
než kolik jsem popsal v tomto krátkém přehledu. Lze v něm definovat vlastní
funkce, má podmínky, smyčky, umožňuje práci s jednoduchými poli, formátovaný
výstup, atd. Složitější programy je pochopitelně možné předávat gawku ze souboru
(parametr -t). Příkladem použití gawku v praxi bylo generování tabulek
závislostí zdrojových souborů u starších verzí Linuxu.
GNU Awk 2.15 |
Hodnocení: 9,0 z 10 |
Autor: FSF |
Cena: - |
Typ: freeware |
+ |
mocný nástroj |
- |
další jazyk na naučení |
Vytlačiť článok
Pozn.: články boli naskenované ako text a preto obsahujú aj zopár chýb. Taktiež neručíme za zdrojové kódy (Asm, C, Arexx, AmigaGuide, Html) a odkazy na web. Dúfame, že napriek tomu vám táto databáza dobre poslúži.
Žiadna časť nesmie byť reprodukovaná alebo inak šírená bez písomného povolenia vydavatela © ATLANTIDA Publishing
none
|