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.