Přeskočit na obsah

Awk

Z Wikiknih

awk je nástroj navržený pro zpracování textových dat, načítaných ze souboru nebo přímo z datového proudu. Jeho název vychází z počátečních iniciál příjmení autorů původní verze - Alfreda V. Aho, Petra J. Weinbergera a Briana W. Kernighana.

Awk, to je zároveň programovací jazyk, který pracuje s řetězci, asociativními poli (kde jsou jednotlivé položky pole indexovány řetězci) a regulárními výrazy.

Awk je jedním z nejstarších unixových nástrojů, zvláště mocným ve spojení s rourami, který se dodnes používá ve všech moderních operačních systémech, vycházejících z Unixu. Nejde však o původní awk, ale jeho klony (i když s původní aplikací se můžete setkat také). Vlastní příkaz awk je tak většinou pouze symbolickým odkazem.

Jiné implementace awk

[editovat | editovat zdroj]

Awk byl původně napsán v r.1977 jako součást distribuce UNIX v.7

nawk
V r 1985 autoři rozšířili možnosti jeho skriptovacího jazyka a přidali možnost uživatelsky definovat vlastní funkce. Tento skriptovací jazyk byl pak popsán v knize "The AWK Programming Language", vydané r. 1988 a modifikovaná verze programu zahrnuta do distribuce UNIX System V. Aby bylo možno identifikovat tuto inovovanou verzi programu awk, byla nazvána nawk (zkratka z "new awk"). Tato verze pak byla uvolněna k volnému použití r. 1996 a je stále spravována Brianem Kernighanem.
gawk
(zkratka z "GNU verze awk") byl napsán jako GNU implementace awku v době kdy ještě nebyl uvolněn. Oproti původnímu awk má navíc např. funkce pro práci s časovým razítkem (timestamp)
mawk
je implementace vycházejícího z původního awk vytvořená Mikem Brenanem (název byl vytvořen pravděpodobně přidáním počáteční iniciály jeho jména). Oproti jiným implementacím by měl být rychlejší, díky odlišné práci s regulárními výrazy (více na http://www.root.cz/clanky/regularni-vyrazy-6/). Na druhou stranu však má omezení pokud jde o počet a velikost záznamů.

Existují i implementace pro jiné operační systémy např. stránka

http://short.stop.home.att.net/freesoft/txtfrmt.htm - obsahuje odkazy na verze awk pro MS Windows/DOS

Jak pracuje awk

[editovat | editovat zdroj]

Awk postupně načítá ze vstupního proudu dat jednotlivé řádky, a v nich postupně vyhledává vzorky - znakové řetězce, které mohou být určeny např. regulárními výrazy. Pokud nějaký najde, pak provede s řádkem zadanou akci. Po aplikaci sady vzorků a k nim definovaných akcí, pokračuje awk dalším řádkem.

  • Řádek nevyhovující žádnému vzorku awk ignoruje
  • Pro každý vzorek je akce vykonávána samostatně, tudíž pro řádek vyhovující více vzorkům může být na výstupu více řádků.
  • Pokud není nastaven žádný vzorek, pouze akce, tak jsou zpracovány postupně všechny řádky.

Příkazy lze zadat přímo na řádku, nebo v případě rozsáhlejší sady příkazů pomocí skriptu

Příklad
user@stroj:~/$ awk /vzorek/ soubor_dat.txt
V testovém souboru soubor_dat.txt jsou vyhledány a na standardní výstup vytištěny řádky, které obsahují řetězec "vzorek". Následující příklad vrátí výsledek totožný, přesto si lze povšimnout několika podstatných detailů:
user@stroj:~/$ awk '/vzorek/ { print $0}' soubor_dat.txt
  • V prvním příkladě je vykonána výchozí akce awku pro řádek, který odpovídá vzorku - print
  • V prvním příkladu není užito jednoduchých uvozovek, tudíž se na všechny položky vztahují pravidla o expanzi proměnných, atp.
  • Druhý příklad názorně demonstruje použití vzorku a akce

Je-li vyhledávaných vzorků nebo spouštěných akcí více, jsou od sebe odděleny středníkem - ;

user@stroj:~/$ awk '/vzorek/ { print $1};/jiny_vzorek/ { print $2}' soubor_dat.txt
Slovy
Najdeš-li na řádku řetězec "vzorek", tak pošli na výstup první položku řádku, dále zkontroluj není-li někde na řádku také řetězec "jiny_vzorek", pokud ano, tak pošli na výstup druhou položku řádku. Není-li na řádku žádný z těchto vzorků, tak pokračuj dalším řádkem

Jelikož je řetězec "vzorek" obsažen i v druhém hledaném řetězci "jiny_vzorek", budou postupně za sebou posílány na výstup obsahy první i druhé položky řádku obsahujícího řetězec "jiny_vzorek"

Jak se awk implicitně dívá na soubor

[editovat | editovat zdroj]
První_řádek Druhá_položka Třetí_položka
Druhý_řádek Druhá_položka Třetí_položka
Třetí_řádek Druhá_položka Třetí_položka

Tak tohle je obsah souboru soubor_dat.txt. Awk při jeho zpracování dělí proud znaků do záznamů (record) a ty do jednotlivých položek (fields). Jelikož je implicitním oddělovačem záznamů konec řádku, odpovídá zpravidla i obsah záznamu, který zpracovává awk obsahu jednoho řádku. Implicitním oddělovačem položek je bílý znak (mezera nebo tabulátor)

Oddělovače jsou uloženy v proměnných RS (oddělovač záznamů) a FS (oddělovač položek) a změnou obsahu těchto proměnných lze přetypovat i implicitní nastavení. Oddělovač položek lze přetypovat i přímo při spuštění awk volbou -F následovanou novým oddělovačem, který může být tvořen i víceznakovým řetězcem, nebo regulárním výrazem (nezapomeňte však, že je nutno ošetřit znaky které by mohl shell nějakým způsobem interpretovat).

Číslo aktuálně zpracovávaného záznamu (zpravidla řádku) je uloženo v proměnné NR a počet položek (sloupců) zase v proměnné NF. Při zpracovávání obsahu řádku se na jednotlivé položky odkazujeme jejich pořadovým číslem ( $1 - první sloupec, $2 - druhý sloupec,.. pozn: položka $0 obsahuje celý řádek)

Příklad
user@stroj:~/$ awk '{ print $1}' soubor_dat.txt
První_řádek
Druhý_řádek
Třetí_řádek

Zpracování výstupu

[editovat | editovat zdroj]

Při zpracování výstupu lze používat i příkazové konstrukce:

if (podmínka) příkaz else příkaz

user@stroj:~/$ awk '{ if (NR==2) print $2; else print $1}' soubor_dat.txt
První_řádek
Druhá_položka
Třetí_řádek
user@stroj:~/$

while (podmínka) příkaz

do příkaz while (podmínka)

for (výraz;výraz;výraz) příkaz

break

continue

next

delete pole[index]

exit výraz

Relační výrazy

[editovat | editovat zdroj]

Kombinace vzorků

[editovat | editovat zdroj]

Jednotlivé vzorky lze spojovat logickými operátory && (AND), || (OR) a ! (NOT)

Příklad
user@stroj:~$ awk '$1 >= "1" && $1 < "T" && $1 !~ /^D.*k$/ {print $0}' soubor_dat.txt
První_řádek Druhá_položka Třetí_položka
user@stroj:~$
Výrazu vyhoví pouze ty řádky, jejichž první položka je větší než "1" a zároveň menší než "T" s současně neobsahuje textový řetězec začínající na "D a končící písmenem "k" Pro větší názornost, rozšíříme-li obsah souboru soubor_dat.txt
Příklad
user@stroj:~$ cat soubor_dat.txt
První_řádek Druhá_položka Třetí_položka
Druhý_řádek Druhá_položka Třetí_položka
Třetí_řádek Druhá_položka Třetí_položka
Čtvrtý_doplňkový_řádek
Doplňkový_řádek číslo_pět
Dodatečný řádek

user@stroj:~$ awk '$1 >= "1" && $1 < "T" && $1 !~ /^D.*k$/ {print $0}' soubor_dat.txt
První_řádek Druhá_položka Třetí_položka
Dodatečný řádek
user@stroj:~$
Jak vidno výrazu vyhověl rovněž "Dodatečný řádek", protože jeho první položka, řetězec "Dodatečný" sice začíná na "D", ale nekončí na "k"

BEGIN a END

[editovat | editovat zdroj]

Potřebujeme-li aby awk vykonal nějakou akci před vlastním zpracováním proudu dat, nebo po, použijeme klíčového slova BEGIN nebo END. Jde v podstatě o speciální typ vzorků, které ovšem nejsou testovány pro každý záznam, ale naopak, jejich akce jsou spuštěny před začátkem zpracování dat (BEGIN) a jeho skončení (END).

Příklad
user@stroj:~/$ awk 'BEGIN { print "ještě jsem nezačal.."};END { print "a už jsem skončil.."}' soubor_dat.txt
ještě jsem nezačal..
..a už jsem skončil
user@stroj:~/$

Jako akce se označuje sekvence příkazů pro awk. Ty se od sebe oddělují buďto prázdnými řádky

awk 'BEGIN{hodnota=0}
     {hodnota+=$5}
     END{print hodnota}
    ' soubor_s_daty

nebo středníky

awk 'BEGIN{hodnota=0};{hodnota+=$5};END{print hodnota}' soubor_s_daty

Proměnné a výrazy

[editovat | editovat zdroj]

Jak už naznačuje výše uvedený příklad, awk pracuje také s proměnnými a matematickými výrazy

Volby pro awk

[editovat | editovat zdroj]

Použitelné proměnné - shrnutí

[editovat | editovat zdroj]
Proměnná Popis
RS oddělovač záznamů
NR číslo aktuálně zpracovávaného záznamu
FS oddělovač položek
NF počet položek aktuálního záznamu
FILENAME jméno aktuálního vstupního souboru (v případě standardního vstupu "-"

Další zdroje

[editovat | editovat zdroj]