Awk

A HupWiki-ből...

Tartalomjegyzék

AWK

Az awk egy mintakereső és -feldolgozó program, saját programozási nyelvvel. E nyelv különlegessége, hogy adatvezérelt. Az awk elsősorban adatlisták szűrésére alkalmas.

Használat:

  • awk ' PROGRAM ' ÁLLOMÁNY(OK)
  • Sorban beolvassa a bemeneti ÁLLOMÁNY(OK) tartalmát, miközben az AWK nyelven írt PROGRAM-ban leírt műveleteket végrehajtja.
  • Ha nem adunk meg állományt, a szabványos bemenetről olvas.
  • gawk: Az eredeti awk program GNU változata. Többet tud elődjénél.
  • #! /bin/awk -f: Ha az AWK forrásprogramot állományban tároljuk el, az állomány első sorába ezt a megjegyzést (parancsértelmező fejlécet) írjuk, valamint futtathatóvá tesszük az állományt, akkor az AWK programot a shell scriptek mintájára a ./PROGFÁJL ÁLLOMÁNY(OK) paranccsal is lefuttathatjuk.

AWK forrásprogram felépítése

  • Minden AWK forrásprogram szabályok (rule) sorozata. Minden szabály tartalmazhat egy mintát (pattern) és egy hozzá tartozó tevékenységet avagy akciót (action). Az akciót különféle utasításokból (statement) állíthatjuk össze.
  • A szabályok alakja: /MINTA/ {AKCIÓ}
  • A szabályokat egymástól sortöréssel vagy pontosvesszővel lehet elválasztani
  • A feldolgozás során a bemenet tartalmát rekordokra (record) bontja, ezek alapesetben a bemenet sorai lesznek. A rekordokat szintén tovább bontja mezőkre (field), amiket alapesetben az illető sor szavai képviselnek.
  • A bemenet feldolgozása rekordonként történik. Minden rekordot megpróbál illeszteni sorban az összes szabály mintájára, az első szabálytól kezdve. Ha a rekord illeszkedett egy szabály mintájára, akkor végrehajtódik a hozzá tartozó akció. Végül az összes szabály ellenőrzése után rátér a következő rekord feldolgozására.
  • A szabályok sorrendje fontos, hiszen a mintákra való illeszkedés ellenőrzése, s így az akciók végrehajtásának sorrendje ettől függ!
  • Hiányzó minta esetén az illető akció minden rekord esetén lefut.
  • A szabályokból az akciót is el lehet hagyni a kapcsos zárójelekkel együtt. A hiányzó akció ekvivalens a {print} akcióval, ami kiírja az egész rekord tartalmát (ld. később).
  • Vigyázat! A {} páros az üres akciót jelöli, tehát nem egyezik meg az előbb említett esettel (ti. az akció elhagyásával)!
  • Bármely mintát vagy utasítást folytathatjuk a következő sorban, ha az aktuális sort a \ jellel zárjuk.
  • Az akciók utasításlistája akár több sorból is állhat. Egy sorba több utasítást is írhatunk, ha őket pontosvesszővel (;) választjuk el egymástól. Hasonlóan, a pontosvessző használatával több szabályt is írhatunk egy sorba.
  • Szóközöket és tabulátorokat tetszés szerint használhatunk a műveleti jelek, operandusok, utasítások, paraméterek, stb. között. Üres sorok szintén megengedettek.
  • #: A sor végéig tartó megjegyzés (comment) kezdetét jelzi.
  • Az AWK különbséget tesz a kisbetűk és nagybetűk között!

AWK minták felépítése

  • Minden minta egy logikai feltételt fogalmaz meg. Ha a feltétel teljesül egy konkrét rekord esetén, akkor azt mondjuk, hogy a rekord illeszkedik a mintára. Fontos, hogy olyan feltételt is megfogalmazhatunk, amely nem (vagy nemcsak) a rekord tartalmától függ, hanem pl. valamely változótól!
  • Elemi minták:
    • (MINTA): csoportosítás (műveleti sorrend felülbírálása), MINTÁ-ra illeszkedik
    • !MINTA: logikai tagadás (negáció)
    • /REGKIF/: igaz, ha az egész rekord illeszkedik a reguláris kifejezésre
    • KIF~/REGKIF/: igaz, ha a KIF kifejezés (ld. később) mint szöveg illeszkedik a reguláris kifejezésre
    • KIF!~/REGKIF/: igaz, ha a kifejezés nem illeszkedik a REGKIF-re
    • relációs kifejezések: tetszőleges kifejezés, amely relációs jelet tartalmaz
    • BEGIN: csak a bemenet feldolgozása előtt teljesül
    • END: csak a bemenet feldolgozása után teljesül
  • Összetett minták:
    • MINTA1&&MINTA2: logikai ÉS (konjunkció)
    • MINTA1||MINTA2: logikai MEGENGEDŐ VAGY (diszjunkció)
    • MINTA1,MINTA2: Rekordok tartományára illeszkedik, kezdve egy olyan rekorddal, amely MINTA1-re illeszkedik, egészen egy olyan rekordig, amely MINTA2-re illeszkedik. Nem kombinálható semmilyen más mintával!
  • A BEGIN és END mintákhoz mindig meg kell adni az akciót is! Továbbá ezek a speciális minták nem kombinálhatók semmilyen más mintával, valamint nem alkalmazható rájuk a csoportosítás és a negáció sem!
  • A BEGIN mintához tartozó akció pontosan egyszer hajtódik végre, mégpedig a legelső bemeneti rekord feldolgozása előtt. Ez akkor is így történik, ha több bemeneti állományt adtunk meg.
  • Hasonlóan, az END mintához tartozó akció is pontosan egyszer, az utolsó bemeneti rekord feldolgozása után hajtódik végre. Ezt az awk program befejeződése követi.

Konstansok használata AWK-ban

  • Szám avagy numerikus konstansok (numeric constant):
    • egész számok (pl. 12)
    • valós törtszámok tizedesponttal (pl. 25.3)
    • egész vagy valós szám hatványkitevővel (pl. 1.234e+2=123.4)
  • Szöveges avagy sztring konstansok (string constant):
    • "SZÖVEG"
    • "": üres sztring (0 karakter hosszúságú szöveg)
    • A szövegben a \ speciális (az ún. escape-karakter), így használhatók pl. a következő escape-szekvenciák: \\ (közönséges \), \" (közönséges idézőjel), \n (sortörés), \t (tabulátor).
  • Konstans reguláris kifejezések (regular expression constant):
    • /REGKIF/
    • A reguláris kifejezésen belül a \ speciális, így használhatók a \\ (közönséges \) és \/ (közönséges /) karakterpárosok.

Változók használata az AWK-ban

  • Az AWK-ban a változók élettartama dinamikus: az első használatkor automatikusan létrejönnek (nem kell őket deklarálni).
  • A változók neve betűket, számokat és aláhúzásjelet (_) tartalmazhat, és nem kezdődhet számjeggyel.
  • Változók típusai:
    • numerikus változók (valós számokat tárolnak)
    • szöveges változók avagy sztringek (string)
    • egydimenziós tömbök (ld. később)
  • A tömböket kivéve minden változó típusa dinamikus, azaz a használattól függően változik! Ez a tömbelemekre is vonatkozik (ld. később).
  • Egy változó típusát nem lehet tömbről numerikusra vagy sztringre változtatni, és viszont!
  • A változók értékét az awk automatikusan konvertálja számmá vagy szöveggé, szintén a használati módtól (művelettől, függvénytől) függően. Ha a szöveget nem lehet számmá konvertálni (mert nem egy érvényes alakú számot tartalmaz), nullát kapunk.
  • Manuális konverzió:
    • szövegből szám: adjunk hozzá 0-t
    • számból szöveg: fűzzük hozzá az üres sztringet ("")
  • NÉV=ÉRTÉK:
    • Értékadás egy létező változónak, vagy új változó létrehozása. A változó típusa ÉRTÉK típusa lesz.
    • A C programozási nyelv egyéb értékadó, növelő és csökkentő műveletei is használhatók (ld. később).
    • Az ÉRTÉK természetesen nemcsak konstans, hanem kifejezés is lehet.
    • Többszörös értékadás (NÉV1=NÉV2=ÉRTÉK) is megengedett.
  • NÉV:
    • a változó aktuális értékét jelöli
    • Definiálatlan (ti. amelyiknek eddig nem adtunk értéket) változó értéke az üres sztring ("") ill. 0.

Az AWK beépített változói

  • Az awk program indulásakor már létezik jónéhány különleges, beépített változó (built-in variable). Ezek neve egységesen csupa nagybetűből áll, és tartalmuk egyrészt a felhasználónak szóló fontos információkat hordoz, másrészt némelyikük az awk program működését ill. a bemenet feldolgozásának módját vezérli.
  • FILENAME: Az aktuális bemeneti állomány neve, ill. - a szabványos bemenet esetén. A BEGIN minta akcióján belül definiálatlan.
  • FNR: az aktuális rekord sorszáma az aktuális bemeneti állományon belül
  • FS: bemeneti mezőhatároló karakter (input field separator, ld. később), kezdetben a szóköz
  • IGNORECASE: Ha értéke nemzérus, akkor a sztringek összehasonlítása ill. a reguláris kifejezések illesztése nem különbözteti meg a kisbetűket a nagyoktól. Alapesetben értéke definiálatlan (effektíve nulla).
  • NF: az aktuális rekord mezőinek száma (number of fields)
  • NR: Az aktuális rekord sorszáma az eddig feldolgozott bemenet tekintetében. Egy bemeneti állomány ill. a szabványos bemenet esetén egyenlő az FNR-rel.
  • OFS: Kimeneti mezőhatároló (output field separator, ld. később), kezdetben a szóköz. Értéke tetszőleges szöveg lehet, nemcsak egy karakter.
  • ORS: Kimeneti rekordhatároló (output record separator, ld. később), kezdetben a sortörés. Ez is tetszőleges szöveget tartalmazhat.
  • RS: bemeneti rekordhatároló karakter (input record separator, ld. később), kezdetben a sortörés

Tömbök használata az AWK-ban

  • Lehetőség van egydimenziós tömbök (vektorok) használatára is. Fontos, hogy a tömb méretét nem kell előre lerögzíteni, továbbá a tömbelemek indexe tetszőleges szöveg lehet (a számokat is szöveggé konvertálja)! Az ilyen tömböket asszociatív tömböknek (associative array) nevezik.
  • A tömbök nevét a változónevek mintájára adhatjuk meg.
  • A tömb vegyesen tartalmazhat numerikus és szöveges elemeket is!
  • NÉV[INDEX]=ÉRTÉK:
    • Értékadás egy létező tömbelemnek, vagy új elem beszúrása. Az elem típusa ÉRTÉK típusa lesz. A tömb is létrejön, ha még nem létezett.
    • A C programozási nyelv egyéb értékadó, növelő és csökkentő műveletei is használhatók (ld. később).
    • Az INDEX és az ÉRTÉK konstans és tetszőleges kifejezés is lehet.
  • NÉV[INDEX]:
    • a megadott indexű tömbelem aktuális értékét jelöli
    • Definiálatlan elem értéke az üres sztring ("") ill. 0.
  • INDEX in NÉV: Ez a logikai reláció csak akkor igaz, ha a tömbnek van INDEX indexű eleme. Lásd még: for, while, do...while, if utasítások.
  • delete NÉV[INDEX]: a megadott indexű tömbelem kitörlése
  • delete NÉV: A tömb összes elemének kitörlése. Vigyázat, a tömb továbbra is létezni fog, csak üres lesz!

Az AWK kifejezések felépítése

  • A minták és az utasítások megadásához használhatunk különféle kifejezéseket (expression). Az ezeket felépítő építőkövek: konstansok, változók, műveleti jelek, függvények, segédjelek (pl. zárójelek, vessző).
  • (KIF): csoportosítás (műveleti sorrend felülbírálása)
  • Műveletek, relációk:
    • Aritmetika valós számokon: + (előjel és összeadás is), - (előjel és kivonás is), ^ (hatványozás), *, /, % (osztási maradék)
    • Növelés (increment), csökkentés (decrement): ++, -- (mindkettő prefix és postfix használatban is)
    • Sztring összefűzés, konkatenáció: egymás mellé írás, illetve szóköz
    • Mező értékének használata (mezőhivatkozás): $KIF (ld. később)
    • Értékadás (assignment): =, +=, -=, *=, /=, %=, ^=
    • Összehasonlító relációk: <, <=, >, >=, ==, !=
    • Mintaillesztő relációk: KIF~/REGKIF/, KIF!~/REGKIF/
    • Tömbelem létezésének vizsgálata: INDEX in NÉV
    • Logikai műveletek: ! (negáció), && (konjunkció), || (diszjunkció)
    • Feltételes kifejezés: KIF1?KIF2:KIF3 (mint a C prog. nyelvben)
  • Az összehasonlítás csak akkor történik numerikusan, ha a reláció mindkét oldalán szám konstans, numerikus változó vagy mezőhivatkozás áll. Máskülönben az értékek szövegesen (lexikografikusan, azaz az ábécé rendet követve) lesznek összehasonlítva!
  • A logikai műveletek, a feltételes kifejezés és a vezérlési szerkezetek szempontjából hamisnak (false) minősül az üres sztring ("") és a nulla. Minden más érték igaznak (true) számít.
  • A relációk numerikus értéke igaz esetén 1, különben 0. Ez az összehasonlító és mintaillesztő relációkra, továbbá az in relációra és a logikai műveletekre is vonatkozik.
  • A mintaillesztő relációk igazak, ha a bal oldali kifejezés mint szöveg illeszkedik (~) ill. nem illeszkedik (!~) a jobb oldali reguláris kifejezésre.
  • A feltételes kifejezésben először KIF1 lesz kiértékelve. Ha igaz, akkor KIF2, különben KIF3 lesz kiszámolva, s ők adják a kifejezés értékét is.
  • Numerikus függvények:
    • Trigonometria: sin(KIF), cos(KIF)
    • sqrt(KIF): négyzetgyökvonás
    • Exponens, logaritmus: exp(KIF), log(KIF)
    • int(KIF): egésszé konvertálás csonkolással (truncation)
  • Szöveges függvények:
    • index(SZÖVEG,RÉSZ): A RÉSZ szöveg legelső előfordulásának pozíciója SZÖVEG-ben. Ha nincs ilyen rész, akkor nullát ad vissza.
    • length(SZÖVEG): a megadott sztring hossza karakterekben
    • split(SZÖVEG,TÖMB,HAT): SZÖVEG-et a HAT határolójel mentén darabokra bontja, a darabokat a megadott tömbben eltárolja, majd visszaadja a darabok számát. A SZÖVEG változatlan marad. A tömb elemei a darab sorszámával (pont nélkül) lesznek indexelve. HAT reguláris kifejezés is lehet.
    • substr(SZÖVEG,IND): a szöveg IND sorszámú karakterén kezdődő részét adja vissza
    • substr(SZÖVEG,IND,HOSSZ): mint előbb, de legfeljebb HOSSZ karakterből álló részt ad vissza
    • tolower(SZÖVEG): visszaadja a SZÖVEG kisbetűssé konvertált értékét
    • toupper(SZÖVEG): visszaadja a SZÖVEG nagybetűssé konvertált értékét

Mezők elérése AWK-ban

  • A bemenet rekordokra bontását, ill. azoknak mezőkre bontását két beépített változó vezérli. Az RS változó tartalma egy karakter (alapesetben sortörés), ez jelzi a rekordokat elválasztó karaktert. Hasonlóan, az FS változó tartalma (alapesetben szóköz) határozza meg, mi határolja a mezőket a rekordokon belül. Ha az FS értéke a szóköz (alapeset), akkor a mezőket legalább egy szóköz vagy tabulátor választja el.
  • Az aktuális rekord mezőinek a számát az NF beépített változó tárolja.
  • A mezők típusa ugyancsak numerikus vagy szöveges lehet, az aktuális használattól függően. Összehasonlításkor a mezők tartalmát számnak tekinti az awk, ha az valóban egy érvényes számot tartalmaz, továbbá ha a másik tag szám konstans, numerikus változó vagy mezőhivatkozás .
  • $KIF:
    • Az aktuális rekord megadott sorszámú mezőjének tartalma. Ezt a jelölést mezőhivatkozásnak (field reference) nevezzük.
    • Tetszőleges kifejezést is használhatunk, pl. $(2*3) a hatodik mezőt jelzi. Természetesen a negatív értékek nem megengedettek.
    • $NF: az aktuális rekord utolsó mezőjének tartalma
    • $0 (dollárjel és nulla): az aktuális rekord teljes tartalma
  • $KIF=ÉRTÉK:
    • egy adott mező - ill. KIF = 0 esetén a rekord - értékének módosítása
    • Ha $0 tartalmát változtatjuk meg, akkor minden mező új értéket kap. Ha viszont egy mező tartalmát módosítjuk, akkor $0 értékét az awk újraépíti oly módon, hogy a mezőket az OFS értéke határolja majd el.
    • Ha KIF > NF, akkor a mezők számát kibővíti, és NF-et is módosítja. Szükség szerint a közbülső helyekre új mezőket szúr be, ezek értéke az üres sztring ("") lesz. Végül pedig $0 tartalmát is újraszámítja az előbb leírt módon.

Az AWK akciók felépítése

  • A szabályok akcióját alkotó utasítások építőelemei:
    • a korábban már látott delete utasítás
    • értékadó, növelő és csökkentő kifejezések
    • vezérlési szerkezetek (ld. lent)
    • egyéb utasítások (ld. következő dia)
  • {UTASÍTÁSOK}: összetett utasítás, utasításblokk/-lista
  • if (FELTÉTEL) UTASÍTÁS else UTASÍTÁS: szelekciós vezérlés
  • while (FELTÉTEL) UTASÍTÁS: előfeltételes ismétléses vezérlés
  • do UTASÍTÁS while (FELTÉTEL): végfeltételes ismétléses vezérlés
  • for (KIF1;KIF2;KIF3) UTASÍTÁS: számlálásos ismétléses vezérlés
  • for (INDEX in NÉV) UTASÍTÁS: Diszkrét ismétléses vezérlést valósít meg. Az INDEX változó sorban felveszi a NÉV nevű tömb elemeinek indexét, miközben a megadott utasítás végrehajtódik.
  • break, continue: Kilépés a ciklusból, ill. rátérés a ciklus következő iterációjára (for, while és do...while esetén használhatók). Mindig az őket körbevevő legbelső ciklusra vonatkoznak!
  • exit: A bemenet feldolgozásának azonnali befejezése. Ha nem az END minta akciójában használjuk, akkor az esetleges END minta akciója végrehajtódik, különben az awk rögtön befejezi működését.
  • print LISTA: Kiírja a vesszővel tagolt kifejezéslista tagjainak értékét, majd az ORS tartalmát (alapesetben egy sortörést). A kiírt értékek közé az OFS tartalma kerül (alapesetben egy szóköz).
  • print: ekvivalens a print $0 utasítással (az aktuális rekord teljes tartalmát kiírja)
  • printf FORMÁTUM,LISTA: formázott kiíratás (mint a C prog. nyelvben)
  • next: Azonnal nekikezd a következő bemeneti rekord feldolgozásához, a legelső szabály mintáját tesztelve. Ha nincs több rekord, akkor az esetleges END minta akciójával folytatja.