Nykyinen versio |
Oma tekstisi |
Rivi 1: |
Rivi 1: |
| {{DISPLAYTITLE:{{lcfirst:{{PAGENAME}}}}}}
| | '''awk'''-ohjelmointikielen avulla voi helposti muuntaa tekstitiedoston rakennetta. awk ja sen laajennettu versio gawk kuuluvat Unix/Linux-käyttäjän perustyökaluihin silloin, kun kyseessä on: |
| '''awk'''-työkalun avulla voi helposti muuntaa tekstitiedoston rakennetta. awk ja sen laajennettu versio gawk kuuluvat Unix/Linux-käyttäjän perustyökaluihin silloin, kun kyseessä on: | | |
| * puhtaan tekstitiedoston muuntaminen riveittäin toiseen muotoon | | * puhtaan tekstitiedoston muuntaminen riveittäin toiseen muotoon |
| * rivien suodattaminen pois tekstistä tavalla, johon [[grep]] ei kykene | | * rivien suodattaminen pois tekstistä tavalla, johon [[grep]] ei kykene |
| * laskujen laskeminen riveillä olevilla numeroilla | | * laskujen laskeminen riveillä olevilla numeroilla |
|
| |
|
| == Johdanto == | | == Käyttö == |
| awk on skriptikieli ja samanniminen tulkki tälle skriptikielelle. Se on tarkoitettu tiedon hakemiseen selkeän rakenteen omaavista tekstitiedostoista ja tämän tiedon esittämiseen siistissä muodossa. Sen kehittäminen aloitettiin jo 1977 AT&T:n tutkimuslaboratoriossa (''[[Bell Labs]]''). Samassa paikassa aloitettiin muutama vuosi aikaisemmin myös [[Unix]]in kehittäminen.
| |
| | |
| awk:n tilalla on monesti käytetty [[Perl]]iä, joka on kehitetty mm. ratkaisemaan samankaltaisia ongelmia kuin awk. awk:n opettelu ei silti ole turhaa, sillä:
| |
| *awk on yksinkertaisempi (tärkeää jos mietit, kumman opettelisit ensin)
| |
| *awk:n syntaksi on säännöllisempi
| |
| *awk löytyy lähestulkoon järjestelmästä kuin järjestelmästä, Perl-tulkki ei
| |
| *[http://pubs.opengroup.org/onlinepubs/009695399/utilities/awk.html IEEE:n Unix-standardi] määrittelee awk:n melko kattavasti, kun taas Perlin parametrit ja syntaksi ovat eläneet päätoteutuksen mukana
| |
| | |
| Tärkeää on siis ymmärtää, että awk ei ole ainoa työkalu tietyntyyppisten ongelmien ratkaisemiseen. Eikä se ole myöskään monipuolisin. Se saattaa kuitenkin monissa tilanteissa olla yksinkertaisempi käyttää kuin Perl-skriptit.
| |
| | |
| == Syntaksi ==
| |
| awk:n syntaksi on lähellä [[C]]:n syntaksia. Seuraavat asiat on kuitenkin syytä huomioida:
| |
| * muuttujilla ei ole tyyppiä ja muunnokset tehdään automaattisesti.
| |
| * taulukkoindekseinä voi käyttää periaatteessa mitä tahansa, tästä on paljon hyötyä niissä tehtävissä, joihin awk on ensisijaisesti tarkoitettu
| |
| * syöttödata pilkotaan automaattisesti $1..n numeroiduiksi kentiksi yleensä välilyönnin kohdalta.
| |
| * virheilmoitusten tulkinta voi olla hankalaa
| |
| | |
| Yksinkertaisimmillaan awk:ta voidaan käyttää riveillä muotoa
| |
| lauseke {komento}
| |
| missä ''lauseke'' voi olla säännöllinen lauseke tai etsittävä merkkijono. Esimerkiksi rivi
| |
| /linux/ {print}
| |
| tulostaisi kaikki rivit, joilla esiintyy sana "linux".
| |
| | |
| == awk-ohjelman käyttö ==
| |
| awk:ta käytetään komentoriviltä antamalla sille syötteenä skripti ja tiedosto, jota tällä skriptillä käsitellään. Skripti voidaan antaa joko komentoriviparametrina tai pidempien skriptien kanssa antamalla parametrina tiedosto, josta skripti ladataan. Eli joko
| |
| awk -f skripti.awk tiedosto.txt
| |
| tai
| |
| awk '/linux/ {print}' tiedosto.txt
| |
| | |
| == Kenttien käsittely ==
| |
| awk:n vahvin puoli on sen kyky käsitellä tiedoston sisältöä kenttinä. Esimerkiksi voimme helposti tulostaa tekstitaulukosta jokaisen rivin kolmannet solut.
| |
| | |
| Tutkitaan esimerkiksi tiedostoa [[Passwd-tiedosto|/etc/passwd]] josta löytyy tietokoneen käyttäjien käyttäjätunnukset. Tämä tiedosto on muotoa
| |
| <pre>
| |
| root:x:0:0:root:/root:/bin/bash
| |
| daemon:x:1:1:daemon:/usr/sbin:/bin/sh
| |
| bin:x:2:2:bin:/bin:/bin/sh
| |
| </pre>
| |
| Leikitään, että haluamme tulostaa tiedostosta käyttäjien nimet. Käyttäjätunnus on jokaisella rivillä ensimmäinen kenttä, jos kentät erotellaan :-merkillä. Tehdään tällainen awk-skripti.
| |
| | |
| Määritellään ensin erotinmerkiksi kaksoispiste asettamalla se muuttujan FS komennolla
| |
| FS = ":"
| |
| Komentoriviltä käytettäessä tämä voitaisiin asettaa valitsimella -F:
| |
| awk -F ":" ....
| |
| Tämän jälkeen awk erottelee jokaiselta riviltä vuorotellen kaksoispisteen erottamat merkkijonot (kentät) muuttujiin $1, $2,... Esimerkiksi tässä tapauksessa ensimmäisellä rivillä $1 olisi "root" ja $2 olisi "x". Nyt voimme tulostaa jokaiselta riviltä ensimmäisen kentät komennolla <tt>print $1</tt>, eli lopullinen awk-skriptitiedosto olisi
| |
| FS = ":"
| |
| { print $1 }
| |
| Toisaalta tämä voitaisiin ajaa myös yhdellä komennolla:
| |
| awk -F : '{print $1}' /etc/passwd
| |
| | |
| == BEGIN- ja END-lohkot ==
| |
| awk käsittelee syötteensä [[grep]]in ja [[sed]]in tavoin rivi kerrallaan. BEGIN- ja END-lohkoissa suoritetaan asiat, jotka on kuitenkin tarkoitus tehdä suoritusaikana vain kerran ennen ja jälkeen varsinaisen syötteen käsittelyä.
| |
| awk 'BEGIN {aluksi} lauseke1 {jokaiselle lauseke1:lle} \
| |
| lauseke2 ... END {lopuksi}' tiedosto
| |
| | |
| == Ehtolauseet ja vertailut ==
| |
| | |
| == Printf ==
| |
| Printf on awk:n funktio, jolla on mahdollista tehdä tarkempia muotoiluja tulostukselle. Se toimii samaan tapaan kuin vastaava funktio [[C]]-kielessä ja sen syntaksi on
| |
| printf "muotoilumerkkijono", muuttuja1, muuttuja2, ...
| |
| Ensimmäisenä annettava merkkijono sisältää tavallista tulostuvaa tekstiä ja voi lisäksi sisältää erikoismerkkejä, joiden paikalle sijoitetaan annettavat muuttujat sopivasti muotoiltuna. Ensimmäinen erikoismerkki käsittelee ensimmäisen parametrina annetun muuttujan, toinen toisen jne.
| |
| | |
| Erikoismerkit alkavat prosenttimerkillä jota seuraa kirjain ja mahdollisesti numeroita (jos halutaan tulostaa prosenttimerkki, on käytettävä merkintää %%). Erikoismerkkejä ovat
| |
| {| border=1
| |
| |-
| |
| |'''Merkki'''
| |
| |'''Selitys'''
| |
| |-
| |
| |%c
| |
| |Tulostaa ASCII-numeroa vastaavan merkin. Esimerkiksi <tt>printf "%c", 65</tt> tulostaisi "A"
| |
| |-
| |
| |%d
| |
| |Tulostaa kokonaisluvun
| |
| |-
| |
| |%i
| |
| |Tulostaa kokonaisluvun
| |
| |-
| |
| |%e
| |
| |Tulostaa luvun halutussa eksponenttimuodossa. Esimerkiksi <tt>printf "%4.3e", 1950</tt> tulostaisi "1.950e+03" (4 merkitsevää numeroa ja eksponenttina 3)
| |
| |-
| |
| |%f
| |
| |Tulostaa desimaaliluvun
| |
| |-
| |
| |%g
| |
| |Tulostaa luvun joko desimaali- tai eksponenttimuodossa sen mukaan, kummassa tarvitaan vähemmän merkkejä
| |
| |-
| |
| |%o
| |
| |Tulostaa etumerkittömän oktaaliluvun
| |
| |-
| |
| |%s
| |
| |Tulostaa merkkijonon
| |
| |-
| |
| |%x
| |
| |Tulostaa etumerkittömän heksaluvun
| |
| |-
| |
| |%X
| |
| |Tulostaa etumerkittömän heksaluvun käyttäen desimaaliluvuille 10-15 isoja kirjaimia
| |
| |-
| |
| |}
| |
| | |
| == Silmukat ==
| |
| | |
| == Muuttujat ==
| |
| Shell-muuttujia voi välittää awk:lle luettelemalla ne parametreissa. Luvun 12 tulostus:
| |
| a=12
| |
| echo '\n' | awk -v a=$a 'END {print a}'
| |
| | |
| {| border=1
| |
| |-
| |
| |'''Muuttuja'''
| |
| |'''Selitys'''
| |
| |-
| |
| |FNR
| |
| |Rivinumero tiedostossa, BEGIN-lohkossa 0.
| |
| |-
| |
| |FS
| |
| |Kentän erotin, vakiona <space>.
| |
| |-
| |
| |NF
| |
| |Kenttien lukumäärä rivissä, BEGIN-lohkossa määrittelemätön.
| |
| |-
| |
| |NR
| |
| |Rivinumero syötteessä kokonaisuutena, BEGIN-lohkossa 0.
| |
| |-
| |
| |OFMT
| |
| |Formaatti numeroille printf-komennossa, oletuksena "%.6g".
| |
| |-
| |
| |OFS
| |
| |print-komennon kenttäerotin, oletuksena <space>.
| |
| |-
| |
| |ORS
| |
| |print-komennon rivierotin, oletuksena <newline>.
| |
| |-
| |
| |RLENGTH
| |
| |match-funktion tuloksen pituus.
| |
| |-
| |
| |RS
| |
| |Rivierotin, vakiona <newline>.
| |
| |-
| |
| |RSTART
| |
| |match-funktion paluuarvo, eli merkkijonon ensimmäisen merkin sijainti rivillä.
| |
| |-
| |
| |}
| |
| | |
| Muuttuja $0 viittaa kulloiseenkin riviin kokonaisuudessaan.
| |
| | |
| {}-lohkojen sisällä voi määritellä muuttujia C-sukuisten kielten tavoin:
| |
| awk 'BEGIN {a=2} {if (NR % a == 0) print $0; else print "---"}'
| |
| | |
| == Funktiot ==
| |
| {| border=1
| |
| |-
| |
| |'''Funktio'''
| |
| |'''Kuvaus'''
| |
| |-
| |
| |sub(ere, repl[, in ])
| |
| |Korvaa rivin ensimmäisen eren replillä.
| |
| |-
| |
| |gsub(ere, repl[, in ])
| |
| |Korvaa rivin kaikki eret repleillä.
| |
| |-
| |
| |length[([s])]
| |
| |Palauttaa parametrin tai koko rivin pituuden.
| |
| |-
| |
| |match(s, ere)
| |
| |Palauttaa eren alun paikan s:ssä.
| |
| |-
| |
| |split(s, a[, fs ])
| |
| |Paloittelee s:n a:han. fs oletuksena FS.
| |
| |-
| |
| |substr(s, m[, n ])
| |
| | -
| |
| |-
| |
| |tolower(s)
| |
| | -
| |
| |-
| |
| |toupper(s)
| |
| | -
| |
| |-
| |
| |close(exp)
| |
| | -
| |
| |-
| |
| |getline
| |
| |Siirtyy seuraavalle riville.
| |
| |-
| |
| |system(exp)
| |
| |Komento awk:n ulkopuolelle.
| |
| |}
| |
| | |
| == Taulukot ==
| |
| | |
| == Esimerkkejä ==
| |
|
| |
|
| Tiedostoa data.txt, jonka sisältö on seuraava: | | Tiedostoa data.txt, jonka sisältö on seuraava: |
Rivi 205: |
Rivi 13: |
|
| |
|
| käsitellään seuraavanlaisen awk-ohjelman avulla: | | käsitellään seuraavanlaisen awk-ohjelman avulla: |
| | |
| # tämä on awk ohjelma apu.awk | | # tämä on awk ohjelma apu.awk |
| # tämä begin-lohko ajetaan aluksi kerran | | # tämä begin-lohko ajetaan aluksi kerran |
Rivi 223: |
Rivi 32: |
|
| |
|
| Kun tiedosto data.txt syötetään ylläkuvatulle awk-ohjelmalle komennolla | | Kun tiedosto data.txt syötetään ylläkuvatulle awk-ohjelmalle komennolla |
| awk -f apu.awk <data.txt> | | |
| | awk -f apu.awk <data.txt</tt> |
|
| |
|
| on tulos seuraava: | | on tulos seuraava: |
| | |
| alkutemput | | alkutemput |
| ---------- | | ---------- |
Rivi 236: |
Rivi 47: |
|
| |
|
| Seuraavalla komennolla etsitään pieniä, alle 100 merkin tiedostoja /etc-hakemistosta: | | Seuraavalla komennolla etsitään pieniä, alle 100 merkin tiedostoja /etc-hakemistosta: |
| | |
| ls -l /etc |awk '$5 < 100 {printf "%6s %s\n",$5,$8}' | | ls -l /etc |awk '$5 < 100 {printf "%6s %s\n",$5,$8}' |
|
| |
|
| | Edellä olevista esimerkeistä voi huomata, että awk:n syntaksi on lähellä C:n syntaksia. Aloittelija saattaa kuitenkin yllättyä siitä että: |
| | * muuttujilla ei ole tyyppiä ja muunnokset tehdään automaattisesti. |
| | * taulukkoindekseinä voi käyttää periaatteessa mitä tahansa, tästä on paljon hyötyä niissä tehtävissä, joihin awk on ensisijaisesti tarkoitettu |
| | * syöttödata pilkotaan automaattisesti $1..n numeroiduiksi kentiksi yleensä välilyönnin kohdalta. |
| | * virheilmoitusten tulkinta voi olla hankalaa |
| | |
| | Awk:n on sanottu joskus olevan "write only language", ja sitä se onkin jos yrittää saada todella monimutkaisesta awk-ohjelmasta selkoa. Omat ohjelmat kannattaa tehdä siten, että kirjoittaa ja testaa ohjelman rivi kerrallaan. Awk on parhaimmillaan lyhyissä muutaman rivin ohjelmissa. |
|
| |
|
| Poimitaan ja siistitään nykyinen resoluutio xrandr-komennon tulosteesta:
| | Awk-ohjelmissa ei ole yleensä mitään rajoitusta käsiteltävien tiedostojen koolle, koska niitä käsitellään vain riveinä ja syöttö/tulostus putkina/virtoina. Awk-ohjelmat pystyvät käsittelemään varsin helposti hyvinkin suuria syöttö/tulostustiedostoja (satoja megatavuja). |
| xrandr -q | awk 'NR==2 {sub(/\+.*\+.*/,"",$3; print $3}'
| |
|
| |
|
| == Muuta == | | == Linkkejä == |
| awk:n on sanottu joskus olevan "write only language", ja sitä se onkin jos yrittää saada todella monimutkaisesta awk-ohjelmasta selkoa. Omat ohjelmat kannattaa tehdä siten, että kirjoittaa ja testaa ohjelman rivi kerrallaan. awk on parhaimmillaan lyhyissä muutaman rivin ohjelmissa.
| |
|
| |
|
| awk-ohjelmissa ei ole yleensä mitään rajoitusta käsiteltävien tiedostojen koolle, koska niitä käsitellään vain riveinä ja syöttö/tulostus putkina/virtoina. Awk-ohjelmat pystyvät käsittelemään varsin helposti hyvinkin suuria syöttö/tulostustiedostoja (satoja megatavuja).
| | *[http://www.cs.uu.nl/~piet/docs/nawk/nawk_toc.html Awk-opas] |
|
| |
|
| ==Aiheesta muualla==
| |
| *[http://www.unix.se/Awk Awk-artikkeli] unix.se-wikissä (ruotsiksi), josta tämä artikkeli on osittain käännetty. [[Keskustelu:Awk|Lisätietoja]].
| |
| *[http://www.cs.uu.nl/~piet/docs/nawk/nawk_toc.html awk-opas]
| |
| *[http://www.cs.utah.edu/dept/old/texinfo/gawk/gawk_toc.html Gawk-opas] | | *[http://www.cs.utah.edu/dept/old/texinfo/gawk/gawk_toc.html Gawk-opas] |
| *[http://www.pement.org/awk/awk1line.txt Havainnollistavia yksirivisiä]
| |
|
| |
|
| [[Luokka:Komentorivin perustyökalut]] | | |
| | |
| | [[Luokka:Komentorivi]] |
| | [[Luokka:Ohjelmat]] |