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.