Menu

Awk, 2. díl

Pokračování vzorů

Už známe vzory ve formě regulárních výrazů /^...$/. Takto zapsaný vzor se porovnává oproti celému načtenému záznamu $0. Vzor můžeme omezit tak, aby vyhledával v jiném řetězci, operátorem ~. Např. $1 ~ /^...$/ odpovídá záznamům, jejichž první pole obsahuje právě 3 znaky. Naopak, vzor $1 !~ /^...$/ odpovídá všem ostatním.

Vzory, ať už jsou to regulární výrazy, porovnávání proměnných, nebo ještě něco jiného, můžeme kombinovat logickými operátory &&, || a !, podobně jako v shellu.

Můžeme také provést nějakou akci pro rozsah záznamů. Pokud zapíšeme vzor ve formě /start/,/stop/, provede se akce pro všechny záznamy počínaje záznamem vyhovujícím vzoru /start/ a konče záznamem vyhovujícím vzoru /stop/.

Další řídící konstrukce

Řídící konstrukce v awk jsou hodně podobné těm v C a jiných vyšších programovacích jazycích, proto je nebudu popisovat podrobně, ale uvedu jen přehled:

if (podmínka) příkaz [ else příkaz ]
while (podmínka) příkaz
do příkaz while (podmínka)
for (proměnná in pole) příkaz     # provede cyklus pro všechny prvky pole,
                                    v náhodném pořadí
break                             # ukončí provádění cyklu
continue                          # přeskočí na další iteraci cyklu
next                              # přeskočí na zpracování dalšího záznamu
delete pole[index]
exit                              # ukončí program (načte konec vstupu)

Pole

Pole v awk se indexují hranatými závorkami. Nemusíme je předem deklarovat, stačí rovnou zapisovat na libovolnou pozici uvnitř pole. Např. { x[NR] = $0 } načte všechny záznamy do pole x. Můžeme jednoduše používat i vícerozměrná pole, stačí od sebe indexy oddělit čárkou, např. M[i,j]. Poslední zajímavostí je, že indexy polí nemusejí být pouze čísla, můžeme použít také libovolné řetězce.

Další speciální proměnné

Kromě proměnných řídících načítání vstupu, o kterých jsme se bavili minule, má awk ještě řadu dalších užitečných proměnných.

ARGC     ... počet argumentů zadaných na příkazové řádce
ARGV     ... pole argumentů zadaných na příkazové řádce
FILENAME ... jméno právě zpracovávaného souboru, nebo - pro standardní
             vstup; v bloku BEGIN není definována
OFMT     ... výstupní formát čísel, defaultně %.6g

Funkce

Podobně jako v shellu, funkce nedeklarujeme, ale přímo definujeme. definice vypadá způsobem function jméno(seznam parametrů) { příkazy }. Konkrétně např. function plus(a, b) { return a+b; } . Návratovou hodnotu vracíme klíčovým slovem return. Je potřeba dát pozor na jednu zradu – uvnitř funkcí nelze definovat žádné lokální proměnné. Tento problém řešíme tak, že přidáme seznam pomocných proměnných do hlavičky funkce, při volání je ale neuvádíme. Bývá zvykem oddělit pomocné proměnné od zbytku větším množstvím mezer. Příklad:

#!/usr/bin/awk -f
function sum(pole,   i, s) {
    s=0
    for (i in pole) s+=pole[i]
    return s
}

BEGIN {
    p[0]=1
    p[1]=2
    p[2]=3
    print sum(p)
}

V awk existuje množství předdefinovaných funkcí – matematických (sin, cos, exp, rand, …), řetězcových (length, sub, gsub, substr, split, …) a jiných. Jejich popis najdete v manuálové stránce awk.

Přepínače awk

Velmi užitečným přepínačem je -v. Umožňuje dovnitř skriptu dostat proměnnou zvenku. Např. při zavolání awk -v x=10 '... skript ...' bude uvnitř skriptu nastavena proměnná x na hodnotu 10. Funguje i pro RS, FS a další interní proměnné.