Kirjoittaja: trilog (14.12.2009)
AWK on ohjelmointikieli, joka on kehitetty käsittelemään pääsääntöisesti tekstimuotoista tietoa. Se kehitettiin Bell Labs -tutkimus- ja kehitysorganisaatiossa, samassa paikassa on kehitetty myös muun muassa C-ohjelmointikieli, vuonna 1977.
AWK on yksi ensimmäisistä tulkattavista ohjelmointikielistä. Siinä on laajalti käytössä teksti-tietotyyppi, assosiatiiviset taulukot ja säännölliset lausekkeet. Sen syntaksi on hyvin C:n kaltainen, mutta esimerkiksi puolipisteen kanssa ei tarvitse olla niin tarkkana: AWK osaa päätellä myös rivitysten perusteella milloin rivi päättyy. AWK:ssa kaikki tyyppimuunnokset tehdään automaattisesti. Tiedostoja käsitellään joukkona tietueita, jotka erotellaan erottimella (oletuksena rivinvaihto). Myös jokainen tietue erotellaan kentiksi määritetyn erottimen kohdalta (oletuksena välilyönti). AWK-ohjelmissa ei ole rajoitusta käsiteltävien tiedostojen koolle, sillä niitä käsitellään syöttö- ja tulostusvirtojen kautta rivi kerrallaan, joten sillä pystyy käsittelemään helposti myös todella isoja tiedostoja.
AWK:sta on nykyään monia eri toteutuksia. Vuonna 1985 kehitetty GNU:n gawk
on nykyään yleisessä käytössä ja se tuleekin muun muassa monessa Linux-jakelussa mukana, siksi tässä esittelyssäkin on keskitytty siihen.
AWK-ohjelma rakenne koostuu yleensä aloitus-, tieto- ja lopetuslohkoista. Tietolohkoja voi olla useampia, joita voidaan määrätä suoritettavaksi tietyin ehdoin.
BEGIN { # alkujutut } { # tämä suoritetaan jokaiselle tekstiriville } /regexp/ { # tämä suoritettaisiin niille riveille, jossa esiintyy sana "regexp" } END { # loppuhommat }
Tekstiä voidaan tulostaa käyttäen print
-lauseketta tai printf
-funkiota tekstin muotoiluun.
BEGIN { print "Hyvää joulua"; }
Kuten esimerkistä voi huomata; kaikkia lohkoja ei tarvitse määritellä.
Seuraavassa määritellään funktio, joka tulostaa n -alkiota Fibonaccin lukuja:
# funktiot pitää määritellä lohkojen ulkopuolella function fib(n) { a = 0; if (n > 1) { b = 1; printf("%d %d ", a, b); # C:stä tuttu printf toimii tulostuksen muotoiluun for (i = 3; i <= n; i++) { c = a + b; a = b # huom. ei puolipistettä b = c; printf("%d ", c); } print; # print-lauseke, joka tässä tulostaa vain rivinvaihdon } else print a; } BEGIN { # tulostetaan 12 ensimmäistä Fibonaccin lukujonon alkiota fib(12) }
Tulostus:
0 1 1 2 3 5 8 13 21 34 55 89
Alla oleva taulukko kuvaa tekstitiedoston rakennetta, johon on kerätty eri henkilöiden kolikkotilanne. Kenttien väliset erottimet ovat sarkaimia.
kenttä 1 | kenttä 2 | kenttä 3 |
Matti | kulta | 3 |
Maija | hopea | 2 |
Uolevi | pronssi | 5 |
Pertti | kulta | 1 |
Jaska | hopea | 4 |
Kalle | kupari | 2 |
Seuraavassa ohjelmassa tulostetaan tekstitiedostosta tietoja ruudulle:
BEGIN { FS = "\t" # määritellään kenttäerotin sarkaimeksi eniten = 0 lkm = 0 kolikkohirmu = "" arvotaulu["kulta"] = 2.4 arvotaulu["hopea"] = 1.85 arvotaulu["pronssi"] = 1.1 } # kentät pilkotaan automaattisesti ja ne tulevat muuttujiin $1, $2, $3 jne. { printf("Henkilöllä %s on %d %skolikko(a)", $1, $3, $2); } eniten < $3 { # pidetään kirjaa siitä, kuka keräsi eniten kolikkoja eniten = $3; kolikkohirmu = $1; } arvotaulu[$2] { # lasketaan vain arvokkaiden kolikkojen arvo (kulta, hopea tai pronssi) printf(", joiden arvo on %.2f", arvotaulu[$2]*$3); lkm++; } { # tulostetaan vielä jokaisen rivin perään piste ja rivinvaihto print "."; } END { printf("%d henkilöä löysi jonkin arvokkaan kolikon eli ", lkm); # seuraavassa lasketaan prosentuaalinen osuus henkilöistä, jotka löysivät jonkin arvokkaan kolikon # huomaa esiasetettu muuttuja (NR), joka kertoo tietueiden lukumäärän printf("%.2f %% henkilöistä.\n", (lkm/NR)*100); printf("Eniten niitä keräsi %s; jopa %d kolikkoa.\n", kolikkohirmu, eniten); }
Tulostus:
Henkilöllä Matti on 3 kultakolikko(a), joiden arvo on 7.20. Henkilöllä Maija on 2 hopeakolikko(a), joiden arvo on 3.70. Henkilöllä Uolevi on 5 pronssikolikko(a), joiden arvo on 5.50. Henkilöllä Pertti on 1 kultakolikko(a), joiden arvo on 2.40. Henkilöllä Jaska on 4 hopeakolikko(a), joiden arvo on 7.40. Henkilöllä Kalle on 2 kuparikolikko(a). 5 henkilöä löysi jonkin arvokkaan kolikon eli 83.33 % henkilöistä. Eniten niitä keräsi Uolevi; jopa 5 kolikkoa.