Az AWK programozási nyelv

Awk Library(Hasznos funkciók gawkban awk-hoz)

Nextfile

A nextfile parancs befejezni az olvasott fájl sorainak feldolgozását, és átugrik a parancssorban megadott következő fájlra. Ez a függvény nem található meg az awk implementációjában. Itt láthatunk két példát a függvény megvalósítására:

# nextfile --- skip remaining records in current file # this should be read in before the "main" awk program function nextfile() { _abandon_ = FILENAME; next } _abandon_ == FILENAME { next }

Ezt a kódrészletet kell beletennünk a main program elejére, így a nextfile() parancs elérhető lesz és definiálunk egy változót is, amelyben majd eltároljuk az aktuális fájl nevét. Amikor ezt meghívjuk, léptet egy sort és beállítja az _abandon_ változó értékét a fájl nevére, így minden sor feldolgozásakor rögtön meghívódik a next parancs, ez mindaddig tart, amíg a megfogalmazott feltétel igaz, tehát amíg a FILENAME meg nem változik. A probléma ezzel függvénnyel csak az, hogy mi történik akkor ha kétszer ugyanaz a fájl szerepel a parancssori paraméterek között. Ennek kiküszöbölésére az FNR változót használjuk. Ugyanis a beolvasott adatmennyiség számlálása, új fájl esetén nullázódik.

# nextfile --- skip remaining records in current file # correctly handle successive occurrences of the same file # Arnold Robbins, arnold@gnu.org, Public Domain # May, 1993 # this should be read in before the "main" awk program function nextfile() { _abandon_ = FILENAME; next } _abandon_ == FILENAME { if (FNR == 1) _abandon_ = "" else next }

Kerekítés(round)

A printf és sprintf működése gyakran függ a telepített C sprintf függvényétől. Ez azt jelenti, hogy egyes esetekben "%.0f" használatakor az sprintf, „elfogulatlanul” kerekít, tehát ,5 esetén nem minden esetben kerekít felfelé. Az alábbi program viszont a gawk-hoz hasonló hagyományos kerekítés szabályainak megfelelően végzi el a kerekítést:

# round --- do normal rounding # # Arnold Robbins, arnold@gnu.org, August, 1996 # Public Domain function round(x, ival, aval, fraction) { ival = int(x) # integer part, int() truncates # see if fractional part if (ival == x) # no fraction return x if (x < 0) { aval = -x # absolute value ival = int(aval) fraction = aval - ival if (fraction >= .5) return int(x) - 1 # -2.5 --> -3 else return int(x) # -2.3 --> -2 } else { fraction = x - ival if (fraction >= .5) return ival + 1 else return ival } }

Ord, Chr

Ez a két parancs egy karakter és a hozzá tartozó ASCII kód közti konverziót teszi lehetővé. Az ord egy karaktert vagy egy karaktersort kap bemenetéül és ezt a karaktert, vagy a karaktersorozat első karakterét felhasználva előállítja a hozzá tartozó ASCII kódot. A chr pedig egy számból állít elő egy karaktert.

Ezen függvények előállítása könnyen megoldható awk-val ezért nem volt szükséges beleépíteni az awk interpreterjébe.

A két függvény egymás inverzei, ezért megoldható, hogy a program magja is közös legyen:

# ord.awk --- do ord and chr # # Global identifiers: # _ord_: numerical values indexed by characters # _ord_init: function to initialize _ord_ # # Arnold Robbins # arnold@gnu.org # Public Domain # 16 January, 1992 # 20 July, 1992, revised BEGIN { _ord_init() } function _ord_init( low, high, i, t) { low = sprintf("%c", 7) # BEL is ascii 7 if (low == "\a") { # regular ascii low = 0 high = 127 } else if (sprintf("%c", 128 + 7) == "\a") { # ascii, mark parity low = 128 high = 255 } else { # ebcdic(!) low = 0 high = 255 } for (i = low; i <= high; i++) { t = sprintf("%c", i) _ord_[t] = i } }

És a tényleges függvények pedig:

function ord(str, c) { # only first character is of interest c = substr(str, 1, 1) return _ord_[c] } function chr(c) { # force c to be numeric by adding 0 return sprintf("%c", c + 0) }

Mint láthatjuk az _ord_init feltölt egy tömböt a BEGIN-ben, az ord függvény pedig ezt a tömböt használja fel a szükséges adatok kinyerésére. A chr pedig egy ügyes trükköt használ fel a karakter előállítására.

Array to String

String tömök feldolgozásakor sokszor egyszerűbb lehet a tömbbeli szövegek egy nagy stringé való összevonása. Erre ad lehetőséget ez a join függvény, amelybe több extra paraméter is bekerült, hogy kellően általános és többfunkciós legyen.

# join.awk --- join an array into a string # Arnold Robbins, arnold@gnu.org, Public Domain # May 1993 function join(array, start, end, sep, result, i) { if (sep == "") sep = " " else if (sep == SUBSEP) # magic value sep = "" result = array[start] for (i = start + 1; i <= end; i++) result = result sep array[i] return result }

Mint láthatjuk, az egyszerű összeolvasztás mellett, megadhatjuk, hogy mely részletét szeretnénk összeolvasztani a tömbnek és milyen szeparátort kívánunk használni, ha az itt megadott érték egyezik a SUBSEP értékével, akkor nem fog szeparátort használni az elemek összekapcsolásakor.