(toiminnot)

hwechtla-tl: Pieni awk-mainos

Kierre.png

Mikä on WikiWiki?
nettipäiväkirja
koko wiki (etsi)
viime muutokset


(nettipäiväkirja 14.10.2014) Oletteko ehkä joskus kuulleet kielestä nimeltä awk? Jos olet käyttänyt Unixia (ks. Unix-aiheisia artikkeleita), olet varmaankin törmännyt siihen ainakin ohimennen. Haluan hiukan mainostaa awkia.

Awk oli pitkään ainoita tarjolla olevia skriptikieliä, jossa on sisäänrakennettu tuki säännöllisille lausekkeille, kohtalaisen hyvät tietorakenteet, automaattinen muistinhallinta ja niin edelleen. Nämä kaikki ominaisuudet ovat tarjolla nykyään paljon yleisemmissä skriptikielissä, kuten Pythonissa, Perlissä, Rubyssa, PHP:ssa ja monissa muissa. Kun skriptikielet ovat yleistyneet, aikoinaan hyvin yleisen awkin ekologinen lokero on pienentynyt lähes olemattomaksi, koska triviaaleihin asioihin (kuten tekstimuunnoksiin säännöllisillä lausekkeilla) on usein luontevampaa käyttää vielä minimalistisempaa sed:a, joka lisäksi on varmasti asennettuna joka järjestelmään.

Mutta! Yksi asia, joka usein jää huomiotta, on se, että awk on oikeasti erittäin monipuolinen ohjelmointikieli, ei pelkästään tekstiprosessointikieli, ja sen käynnistymisaika on erittäin lyhyt. Jos siis olet tekemässä ohjelmaa, jota käynnistetään hyvin tiheästi (esim. CGI-skriptit ovat usein tällaisia), awk on oikeastaan aika hieno kieli sellaisen toteuttamiseen. Awk toimii myös erittäin hyvin yhteen filtteriputkien kanssa, sillä monessa tapauksessa helpoin tapa ATK:yyn on esiprosessoida syöte järkevään järjestykseen, tehdä "tilakoneita" vaativat muunnokset awkilla, ja jatkaa muilla utileilla.

Tässä on muutamien skriptikielten koot levyllä eräässä Debian-asennuksessa. dc on mukana, koska se on pienin ohjelmointikieli, jonka tiedän olevan tarjolla lähes jokaisessa Unixissa.

-rwxr-xr-x 1 root root   43824 Aug 10  2011 /usr/bin/dc
-rwxr-xr-x 1 root root   69096 Jun  1  2012 /bin/sed
-rwxr-xr-x 1 root root  118200 Mar 24  2012 /usr/bin/mawk
-rwxr-xr-x 1 root root 2884984 Mar 13  2014 /usr/bin/python2.7

Käynnistämisen jälkeen mawk lataa jopa vähemmän kirjastoja kuin gsed. Olennainen sarake on VSZ.

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
atehwa    6871  0.0  0.0   4112   312 pts/46   Ss+  10:22   0:00 dc
atehwa    6881  0.0  0.0   6768   608 pts/61   Ss+  10:23   0:00 mawk -f -
atehwa    6885  0.0  0.0  15356   800 pts/66   Ss+  10:23   0:00 sed -f -
atehwa    6892  0.0  0.4  35824  5016 pts/68   Ss+  10:24   0:00 python

Jopa, vaikka tarvitsisi ominaisuuksia, jotka awkista puuttuvat, saattaa olla järkevää järjestellä ohjelma koprosesseina, joissa awk huolehtii ohjelmalogiikasta ja sen kanssa kommunikoiva apuprosessi tarjoaa palvelut, joita awkilla ei pysty toteuttamaan. (Mutta kieltämättä nykyiset skriptikielet ovat tähän myös varsin hyviä.)

Awk on suunniteltu keskimäärin aika hyvin, tiedän siinä vain kolme "syylää":

  1. säännöllisen lausekkeen syntaksi (/jotain/) on oletuksena myös lauseke, jonka arvo kertoo, täsmääkö kyseinen SL viimeksi sisään luettuun riviin. Koska samaa syntaksia käytetään myös antamaan säännöllisiä lausekkeita argumenteiksi tietyille funktioille, jotkin mokat aiheuttavat tosi omituisia bugeja - esimerkiksi, jos SL-syntaksissa oleva argumentti on väärässä kohdassa.
  2. kaikki taulukot ovat hajautuksia, joten elementtien järjestystieto (jos sellaista tarvitaan) pitää pitää erikseen muistissa (hajautuksien sisäinen järjestys on mielivaltainen).
  3. automaattiset tyyppikonversiot (numeroiden muuntaminen merkkijonoiksi ja päin vastoin) aiheuttavat joskus hankalasti löydettäviä bugeja. En kyllä ole törmännyt tähän awkissa.


Viimeinen piirre itse asiassa toimii vähän samaan tapaan kuin Logossa: arvon ulkonäkö määrittää, mitä se on, eli ei ole olemassa erikseen merkkijonoa "0" ja numeroa 0. Siitä on kyllä omituisia seurauksia (huomaa välilyönnit, ne ovat konkatenaatio-operaattoreita):

$ echo | awk '{ print "a" + "a"; print 2 4; print 4 + 4 5; print 4 + (4 5); }'
0
24
85
49

Mutta löysin juuri ainakin yhden kohdan, jossa tyypillä on väliä: 0.0 on epätosi, "0.0" on tosi:

$ echo | awk '0.0 { print "numero"; } "0.0" { print "mj"; }'
mj

Automaattikonversiot ovat yksinkertaisesti huono idea.

Lisää tietoa awkin omituisuuksista: http://www.catonmat.net/blog/ten-awk-tips-tricks-and-pitfalls/


kommentoi (viimeksi muutettu 14.10.2014 15:46)