Erinevus lehekülje "Awk" redaktsioonide vahel

Allikas: Kuutõrvaja
(Sisseehitatud käsud ja funktsioonid)
P
 
(ei näidata 3 kasutaja 33 vahepealset redaktsiooni)
1. rida: 1. rida:
 
 
===Awk===
 
===Awk===
  
53. rida: 52. rida:
 
  bash~$ cat nimed | vaheta.tulbad.awk
 
  bash~$ cat nimed | vaheta.tulbad.awk
  
Samaväärne oleks jätta skriptist esimene interpretaatorit näitev rida ära ja käivitada Awk selliselt
+
Samaväärne oleks jätta skriptist esimene interpretaatorit näitav rida ära ja käivitada Awk selliselt
  
 
  bash~$ awk -f vaheta.tulbad.awk nimed
 
  bash~$ awk -f vaheta.tulbad.awk nimed
  
 
Heaks kombeks on lõpetada skripti nimi viitega interpretaatorile.
 
Heaks kombeks on lõpetada skripti nimi viitega interpretaatorile.
 +
 +
Kui juhtumisi on failis erinevad tulbad eraldatud tühiku asemel ":", või mõne muu märgiga siis saab seda määrata järgnevalt
 +
 +
cat nimed | awk -F':' '{ print $2, $1 }'
 +
 +
Ka arvutada saab awkiga, näiteks konvertida baite megabaitideks
 +
 +
echo '1452360394' | awk '{ foo = $1 / 1024 / 1024 ; print foo "MB" }'
 +
1385.08MB
  
 
===Muutuja ja avaldis===
 
===Muutuja ja avaldis===
77. rida: 85. rida:
 
  }
 
  }
  
    * skript sisaldab vaid algusosa
+
* skript sisaldab vaid algusosa
    * defineeritakse neli muutujat: x, y, w, z
+
* defineeritakse neli muutujat: x, y, w, z
    * sooritatakse tehe arvudega ja stringidega ning trükitakse vastavad tulemused  
+
* sooritatakse tehe arvudega ja stringidega ning trükitakse vastavad tulemused
  
 
===Sisseehitatud käsud ja funktsioonid===
 
===Sisseehitatud käsud ja funktsioonid===
97. rida: 105. rida:
 
Lisaks on olemas sellised sisseehitatud funktsioonid
 
Lisaks on olemas sellised sisseehitatud funktsioonid
  
    * cos(x) - tagastab radiaanides esitatud argumendi koosinuse
+
* cos(x) - tagastab radiaanides esitatud argumendi koosinuse
    * sin(x) - tagastab radiaanides esitatud argumendi siinuse
+
* sin(x) - tagastab radiaanides esitatud argumendi siinuse
    * atan2(x) - tagastab radiaanides esitatud argumendi arkustangensi
+
* atan2(x) - tagastab radiaanides esitatud argumendi arkustangensi
    * int(x) - tagastab argumendi täisosa
+
* int(x) - tagastab argumendi täisosa
    * log(x) - võtab argumendist naturaallogaritmi
+
* log(x) - võtab argumendist naturaallogaritmi
    * sqrt(x) - tagastab argumendi ruutjuure
+
* sqrt(x) - tagastab argumendi ruutjuure
    * rand(x) - genereerib juhusliku arvu vahemikus 0 kuni 1
+
* rand(x) - genereerib juhusliku arvu vahemikus 0 kuni 1
    * srand(x) - tekitab rand() funktsioonile juhusliku alge
+
* srand(x) - tekitab rand() funktsioonile juhusliku alge
  
 
===Valikulause ja tingimused===
 
===Valikulause ja tingimused===
128. rida: 136. rida:
 
Tingimusi seatakse võrdlustehte abil:
 
Tingimusi seatakse võrdlustehte abil:
  
    * < - väiksem
+
* < - väiksem
    * > - suurem
+
* > - suurem
    * = - võrdne
+
* == - võrdne
    * != - mittevõrdne
+
* != - mittevõrdne
    * <= - väiksemvõrdne
+
* <= - väiksemvõrdne
    * >= - suuremvõrdne  
+
* >= - suuremvõrdne  
  
 
Võrdlustehete tulemustega saab sooritada loogilisi tehteid:
 
Võrdlustehete tulemustega saab sooritada loogilisi tehteid:
  
    * ! - eitus
+
* ! - eitus
    * && - ja
+
* && - ja
    * || - või  
+
* || - või  
  
 
Näiteks kirjutame skripti, mis ütleb, kas juhuslik arv on 0.2 < x < 0.8
 
Näiteks kirjutame skripti, mis ütleb, kas juhuslik arv on 0.2 < x < 0.8
169. rida: 177. rida:
 
Kordus sooritab tegevust mitu korda. Kõik näited väljastavad arvud ühest viieni.
 
Kordus sooritab tegevust mitu korda. Kõik näited väljastavad arvud ühest viieni.
  
===While kordus===
+
====While kordus====
  
 
  #!/usr/bin/awk -f
 
  #!/usr/bin/awk -f
179. rida: 187. rida:
 
  }
 
  }
  
===Do kordus===
+
====Do kordus====
  
 
  #!/usr/bin/awk -f
 
  #!/usr/bin/awk -f
189. rida: 197. rida:
 
  }
 
  }
  
===For kordus===
+
====For kordus====
  
 
  #!/usr/bin/awk -f
 
  #!/usr/bin/awk -f
202. rida: 210. rida:
 
Massiivi on otstarbekas kasutada, kui on vaja tegelda paljude samalaadiliste väärtustega.
 
Massiivi on otstarbekas kasutada, kui on vaja tegelda paljude samalaadiliste väärtustega.
  
Näiteks defineerimine massiivi m ja trükime korduse abil välja tema kõigi elementide väärtused:
+
Näiteks defineerime massiivi m ja trükime korduse abil välja tema kõigi elementide väärtused:
  
 
  #!/usr/bin/awk -f
 
  #!/usr/bin/awk -f
229. rida: 237. rida:
 
===Sisendi ja väljundi kasutamine===
 
===Sisendi ja väljundi kasutamine===
  
Skript loeb ootab andmeid sisendisse või klaviatuurilt ning kirjutab väljundisse või ekraanile.
+
Skript loeb andmeid sisendisse või klaviatuurilt ning kirjutab väljundisse või ekraanile.
  
 
  #!/usr/bin/awk -f
 
  #!/usr/bin/awk -f
256. rida: 264. rida:
  
 
Kui andmetega ridu on mitu, teostatakse kontroll iga reaga.
 
Kui andmetega ridu on mitu, teostatakse kontroll iga reaga.
 +
 
===Faili lugemine ja kirjutamine===
 
===Faili lugemine ja kirjutamine===
  
269. rida: 278. rida:
 
  }
 
  }
  
Korduse tingimuseks olev käsu getline lõppkood on nullist suurem seni kuni midagi failist lahteandmed lugeda on.
+
Korduse tingimuseks olev käsu getline lõppkood on nullist suurem seni, kuni midagi failist lähteandmeid lugeda on.
  
 
===Süsteemi programmi väljundi lugemine ja sisendisse saatmine===
 
===Süsteemi programmi väljundi lugemine ja sisendisse saatmine===
286. rida: 295. rida:
 
Awk käsitleb sisendit struktureerituna. Vaikimisi nimetakse kahe järjestikuse reavahetuste vahele jäävat kirjeks. Vaikimisi on jaotatud rida väljadeks tühikute või tabulatsioonimärkide kohalt.
 
Awk käsitleb sisendit struktureerituna. Vaikimisi nimetakse kahe järjestikuse reavahetuste vahele jäävat kirjeks. Vaikimisi on jaotatud rida väljadeks tühikute või tabulatsioonimärkide kohalt.
  
Programmi tööosas saab väljade poole saab pöörduda muutujate $1, $2, $3, $4 jne abil. Muutuja $0 väärtuseks on terve kirje.
+
Programmi tööosas saab väljade poole pöörduda muutujate $1, $2, $3, $4 jne abil. Muutuja $0 väärtuseks on terve kirje.
  
 
Sõltuvalt välja sisust saab teha nendega tehteid. Toome näite, kus leiame tulpadena esitatud lähteandmete ridade summad
 
Sõltuvalt välja sisust saab teha nendega tehteid. Toome näite, kus leiame tulpadena esitatud lähteandmete ridade summad
299. rida: 308. rida:
  
 
  #!/usr/bin/awk -f
 
  #!/usr/bin/awk -f
  BEGIN  { print "Leidame ridade- ja kogusumma" }
+
  BEGIN  { print "Leiame ridade- ja kogusumma" }
 
             {  summa = $1 + $2 + $3 + $4
 
             {  summa = $1 + $2 + $3 + $4
 
                 print $1 " + " $2 " +  " $3 " +  " $4 " = " summa
 
                 print $1 " + " $2 " +  " $3 " +  " $4 " = " summa
306. rida: 315. rida:
 
  END    { print "Kogusumma = "  kogusumma }
 
  END    { print "Kogusumma = "  kogusumma }
  
Siin on esitatud kolm võimalikku skripti osa: algusosa, tööosa ja lõpuosa, kusjuures neile osadele vastavad käsud kirjutatakse loogadesse. Ühes osas kasutatud muutajatel on teises osas sama väärtus (nt kogusumma).
+
Siin on esitatud kolm võimalikku skripti osa: algusosa, tööosa ja lõpuosa, kusjuures neile osadele vastavad käsud kirjutatakse loogadesse. Ühes osas kasutatud muutujatel on teises osas sama väärtus (nt kogusumma).
  
 
Käivitame skripti:
 
Käivitame skripti:
324. rida: 333. rida:
 
Seda saab teha näiteks defineerides skripti algusosas üle vastavate muutujate väärtused:
 
Seda saab teha näiteks defineerides skripti algusosas üle vastavate muutujate väärtused:
  
    * FS - sisendi välja eraldaja (ingl. k. field separator)
+
* FS - sisendi välja eraldaja (ingl. k. field separator)
    * RS - sisendi kirje eraldaja (ingl. k. record separator)
+
* RS - sisendi kirje eraldaja (ingl. k. record separator)
    * OFS - väljundi välja eraldaja (ingl. k. output field separator)
+
* OFS - väljundi välja eraldaja (ingl. k. output field separator)
    * ORS - väljundi kirje eraldaja (ingl. k. output record separator)  
+
* ORS - väljundi kirje eraldaja (ingl. k. output record separator)  
  
 
Kui välja eraldajaks on tühik, siis vastab see Awki vaikimisi toimimisele; sarnaselt on reavahetuse märgi ja kirje eraldajaga. Seades eraldajaks mõne teise sümboli, eraldatakse kirjet või välja selle sümboli kohalt. Kui eraldajaks on enam kui üks sümbol, käsitletakse eraldajat regulaaravaldisena.
 
Kui välja eraldajaks on tühik, siis vastab see Awki vaikimisi toimimisele; sarnaselt on reavahetuse märgi ja kirje eraldajaga. Seades eraldajaks mõne teise sümboli, eraldatakse kirjet või välja selle sümboli kohalt. Kui eraldajaks on enam kui üks sümbol, käsitletakse eraldajat regulaaravaldisena.
333. rida: 342. rida:
 
Lisaks saab kasutada Awkiga seotud muutujaid
 
Lisaks saab kasutada Awkiga seotud muutujaid
  
    * FILENAME - sisendfaili nimi
+
* FILENAME - sisendfaili nimi
    * NF - käesoleva kirje väljade arv (ingl. k. number on fields)
+
* NF - käesoleva kirje väljade arv (ingl. k. number on fields)
    * NR - kirje absoluutne järjekorra number (ingl. k. number of the record)
+
* NR - kirje absoluutne järjekorra number (ingl. k. number of the record)
    * FNR - kirje suhteline järjekorra number; on vajalik mitme sisendfaili kasutamisel  
+
* FNR - kirje suhteline järjekorra number; on vajalik mitme sisendfaili kasutamisel  
  
 
Toome näite nende muutujate kasutamise kohta. Algandmed on sellised
 
Toome näite nende muutujate kasutamise kohta. Algandmed on sellised
 
  
 
  Priit
 
  Priit
358. rida: 366. rida:
 
Nad soovitakse esitada nii, et ühte linna puutuv oleks ühel real, read oleks nummerdatud ning kõige lõppu kirjutataks algandmete faili nimi
 
Nad soovitakse esitada nii, et ühte linna puutuv oleks ühel real, read oleks nummerdatud ning kõige lõppu kirjutataks algandmete faili nimi
  
 +
$ ./skript.awk sisend.txt
 
  1:Priit:Elva:Jüri 15:tel. 15 123
 
  1:Priit:Elva:Jüri 15:tel. 15 123
 
  2:Mart:Jüri:Elva 15:tel. 12 3 15
 
  2:Mart:Jüri:Elva 15:tel. 12 3 15
370. rida: 379. rida:
 
  END { OFS=" "; print "andmefail:", FILENAME }
 
  END { OFS=" "; print "andmefail:", FILENAME }
  
===Aadresseerimine===
+
===Adresseerimine===
  
Regulaaravaldistega saab määrata, millistele sisendi ridadele tööosa käsud rakenduvad. Toome näite, kus tegeldakse vaid Tartu linna temperatuuride keskmistamisega. Algandmed failis temperatuurid on sellised
+
Regulaaravaldistega saab määrata, millistele sisendi ridadele tööosa käsud rakenduvad. Toome näite, kus tegeldakse vaid Tartu linna temperatuuride ööpäevase keskmistamisega. Algandmed failis temperatuurid on sellised
  
 
  linn  kp        6:00  12:00  18:00  24:00
 
  linn  kp        6:00  12:00  18:00  24:00
437. rida: 446. rida:
 
  END  { printf ("\nMõõtmisi teostasid Priit ja Mart\n") }
 
  END  { printf ("\nMõõtmisi teostasid Priit ja Mart\n") }
  
© EENet 2000
+
===Tööosa kasutamise näited===
 +
 
 +
====SQL dump faili tükeldamine====
 +
 
 +
Olgu lähtepunktiks SQL dump fail sql.sql, mis sisaldab sarnaseid INSERT lauseid
 +
 
 +
  INSERT INTO inimesed VALUES (1, 'Mart', 'Kask', 38709067463);
 +
  INSERT INTO inimesed VALUES (2, 'Priit', 'Kask', 38406087465);
 +
  INSERT INTO inimesed VALUES (3, 'Laa', 'Lee', 38701304463);
 +
  INSERT INTO inimesed VALUES (4, 'Koosinus', 'Pii', 31415926535);
 +
  ...
 +
 
 +
Soovides jagada suure faili tükkideks nii, et iga tükk sisaldab 100 kirjet tuleb näiteks öelda
 +
 
 +
  $ awk 'BEGIN{RS="\nINSERT INTO inimesed ";} { i=i+1; j= i % 100 ; if ( j == 1 ) fi=fi+1; if ( i > 1 ) printf \
 +
  ("%s", "INSERT INTO inimesed ") >> "fn_"fi; print >> "fn_"fi ; printf ("%d\n", i); system ("sleep 1") }' sql.sql
 +
 
 +
Skriptis on näha tööosas selliste konstruktsioonide kasutamist
 +
 
 +
* aritmeetilised tehted ja võrdlused
 +
* väljundi formateermine ja faili suunamine
 +
* süsteemse käsu andmine
 +
 
 +
====Tabulatsioonimärkidega edaldatud väljade info kättesaamine failist====
 +
 
 +
$ awk 'BEGIN {FS="\t"; OFS="\t"} {print $1,$2}' large.txt > small.txt
 +
 
 +
===Awkiga sisendi jooksev lugemine ja töötlemine===
 +
 
 +
Jooksvalt töötav awk wrapper e vahekiht mis loeb ühelt töötavalt programmilt väljundit ja käitab vastavalt käske
 +
 
 +
Stardime programmi ja suuname ta väljundi wrapper skriptile, jätame mõlemad taustale tööle
 +
 
 +
/root/bin/programm | /root/bin/wrapper.sh &
 +
 
 +
Skript on ise selline, näiteskriptis loeb ta väljundist vaid kahte numbrit "1" ja "2". Esimesel juhul
 +
saadab ta maili generaator ok, teisel juhul väljastab teate rike ja saadab emaili generaator töötab.
 +
 
 +
#!/usr/bin/awk -f
 +
{
 +
if ( $3 != "1" )
 +
        {
 +
          print " systeem toimib"
 +
          "echo \"generaator ok!\" | mail -s \"generaator ok!\" email@asdf.ee" | getline current_time
 +
        }
 +
else
 +
        {
 +
          print " rike"
 +
          "echo \"generaator t22tab!\" | mail -s \"generaator t22tab!\" email@asdf.ee -c  email@asdf.ee"" | getline current_time
 +
        }
 +
}
 +
 
 +
===Lingid===
 +
 
 +
http://www.ee.ucl.ac.uk/~hamed/misc/awk1line.txt Awk näidete kogumik
 +
 
 +
https://wiki.itcollege.ee/index.php/Awk
 +
 
 +
http://www.cyberciti.biz/faq/bash-scripting-using-awk/ hea lühike manual

Viimane redaktsioon: 6. september 2025, kell 01:35

Awk

Skriptkeel Awk on loodud tekstiliste andmetega manipuleerimiseks. Nimi Awk on akronüüm autorite perekonnanimedest - Aho, Weinberger, Kernighan. Segadust tekitav on paljude Awki versioonide levik, mis erinevad põhiliselt regulaaravaldiste tõlgendamisvõime poolest. Käesolev tegeleb GNU Awki versiooniga, mis muuhulgas tähendab seda, et saab kasutada laiendatud metasümbolite hulka (ingl. k. extended metacharacter set).

Programmeerimise mudel

Awk on sisendi poolt juhitav, mis tähendab, et tööosas näidatud käske rakendatakse vaikimisi Awki sisendisse suunatud andmete igale reale. Vaikimisi käsitleb Awk reana kahe järjestikulise '\n' -i vahele jäävat teksti. Awki skript võib koosneda kolmest osast:

ALGUSOSA - vastavad käsud täidetakse üks kord kõige alguses 

TÖÖOSA - vastavad käsud rakendatakse järjekorras igale sisendi reale 

LÕPUOSA - vastavad käsud täidetakse üks kord kõige lõpus

Neid osi märgitakse Awki skriptis selliselt, käsud kirjutatakse loogade vahele

BEGIN { algusosa käsud }
      { tööosa   käsud }
END   { lõpuosa  käsud }

Awkilik Awki kasutamine toimub rõhuasetusega tööosale. Järgnevas kirjeldame esituse selguse huvides keelevahendite süntaksit algusosa abil.

Awki käivitamine

Awki käske saab anda käsurealt või koondades nad ühte faili. Sellist käivitamisõigusega tekstifaili nimetatakse Awki skriptiks. Awki kasutamisel on võimalik tarvitada IO ümbersuunamist.

Toome näite, kuidas kahes tulbas ja tühikutega eraldatud sisendandmetel tulpade järjekord ära vahetada.

Olgu selline algtekst

bash~$ cat nimed
Miima   1959
Priit   1963
Mart    1940
Peeter  1988

Käsurealt toimub tulpade vahetamine selliselt

bash~$ cat nimed | awk '{ print $2, $1 }'
1959 Miima
1963 Priit
1940 Mart
1988 Peeter

Awki skripti, mis vahetab tulbad, on selline

#!/usr/bin/awk -f
{ print $2, $1 }

Skript sisaldab vaid tööosa ja käivitatakse näiteks nii

bash~$ cat nimed | vaheta.tulbad.awk

Samaväärne oleks jätta skriptist esimene interpretaatorit näitav rida ära ja käivitada Awk selliselt

bash~$ awk -f vaheta.tulbad.awk nimed

Heaks kombeks on lõpetada skripti nimi viitega interpretaatorile.

Kui juhtumisi on failis erinevad tulbad eraldatud tühiku asemel ":", või mõne muu märgiga siis saab seda määrata järgnevalt

cat nimed | awk -F':' '{ print $2, $1 }'

Ka arvutada saab awkiga, näiteks konvertida baite megabaitideks

echo '1452360394' | awk '{ foo = $1 / 1024 / 1024 ; print foo "MB" }'
1385.08MB

Muutuja ja avaldis

Awkis ei ole vaja muutujaid enne kasutamist deklareerida ning puuduvad muutuja tüübid. Sõltuvalt kontekstist käsitletakse muutujat kas stringi või arvuna. Muutuja nimi peab algama tähega ja võib sisaldada peale tähtede ka numbreid ja alakriipse.

Toome näite muutujate kasutamisest

#!/usr/bin/awk -f
BEGIN {
x = 15
y = 2
w = "Tartu"
z = "linn"
x_korda_y = x * y
print x " x " y " = " x_korda_y
tartu_linn = w z
print w " ja " z " on " tartu_linn
}
  • skript sisaldab vaid algusosa
  • defineeritakse neli muutujat: x, y, w, z
  • sooritatakse tehe arvudega ja stringidega ning trükitakse vastavad tulemused

Sisseehitatud käsud ja funktsioonid

Käsku print me oleme juba tarvitanud. Tema järgi kirjutatakse jutumärkidesse teksti ja ilma jutumärkideta muutujad, näites nimi ja x

print "Teie nimi on " nimi "ja te olete " x " aastat vana."

Tihti on otstarbekam kasutada käsku printf, mis sarnaselt C samanimelisele funktsioonile võimaldab väljundit paindlikumalt formateerida. Trükime ekraanile tehte 5/3 tulemuse neljakohalisena, millest kaks on peale koma.

#!/usr/bin/awk -f
BEGIN {
a=5/3
printf ("%4.2f\n", a);
}

Lisaks on olemas sellised sisseehitatud funktsioonid

  • cos(x) - tagastab radiaanides esitatud argumendi koosinuse
  • sin(x) - tagastab radiaanides esitatud argumendi siinuse
  • atan2(x) - tagastab radiaanides esitatud argumendi arkustangensi
  • int(x) - tagastab argumendi täisosa
  • log(x) - võtab argumendist naturaallogaritmi
  • sqrt(x) - tagastab argumendi ruutjuure
  • rand(x) - genereerib juhusliku arvu vahemikus 0 kuni 1
  • srand(x) - tekitab rand() funktsioonile juhusliku alge

Valikulause ja tingimused

if-else

Toome näite valikulausest, kus skript genereerib juhusliku arvu ja teatab, milline see arv on

#!/usr/bin/awk -f
BEGIN {
srand()
x = rand ()
if ( x < 0.5 )
	{
	print x " on vaiksem poolest"
       }
else
	{
    	print x " on yle poole"
	}
}

Tingimusi seatakse võrdlustehte abil:

  • < - väiksem
  • > - suurem
  • == - võrdne
  •  != - mittevõrdne
  • <= - väiksemvõrdne
  • >= - suuremvõrdne

Võrdlustehete tulemustega saab sooritada loogilisi tehteid:

  •  ! - eitus
  • && - ja
  • || - või

Näiteks kirjutame skripti, mis ütleb, kas juhuslik arv on 0.2 < x < 0.8

#!/usr/bin/awk -f
BEGIN {
srand()
x = rand ()
if   ( x > 0.2 && x < 0.8 ) print " 0.2 < " x " < 0.8"
}

Kui tingimusele järgneb vaid üks käsk, siis võib loogad ära jätta ja isegi kirjutada käsu tingimuse järele samale reale.

Võimalik on ka kasutada tuntud

(tingimus) ? (lause 1) : (lause 2)

sarnast konstruktsiooni.

#!/usr/bin/awk -f
BEGIN {
srand()
x = rand ()
print ( x < 0.5) ? x " on vaiksem poolest" : x " on yle poole" 
}

Korduslause

Kordus sooritab tegevust mitu korda. Kõik näited väljastavad arvud ühest viieni.

While kordus

#!/usr/bin/awk -f
BEGIN { x=1
while ( x <= 5 ) {
	print x
	x++
}
}

Do kordus

#!/usr/bin/awk -f
BEGIN { x=1
do {
	print x
	x++
} while ( x <= 5 )
}

For kordus

#!/usr/bin/awk -f
BEGIN {
for (x=1; x <= 5; x++) {
	print x
}
}

Massiiv ja paisktabel

Massiivi on otstarbekas kasutada, kui on vaja tegelda paljude samalaadiliste väärtustega.

Näiteks defineerime massiivi m ja trükime korduse abil välja tema kõigi elementide väärtused:

#!/usr/bin/awk -f
BEGIN {
i=0
m[0] = "mina"
m[1] = "sina"
m[2] = "tema"
while ( i < 3 ) {
      print m[i]
   }
}

Paisktabel

Paisktabel on massiiv, mille indeksiks on string. Defineerime massiivi ja trükime välja teise elemendi.

#!/usr/bin/awk -f
BEGIN {
m["meie"] = "mina"
m["teie"] = "sina"
m["nemad"] = "tema"
print m["teie"]
}

Sisendi ja väljundi kasutamine

Skript loeb andmeid sisendisse või klaviatuurilt ning kirjutab väljundisse või ekraanile.

#!/usr/bin/awk -f
BEGIN {
print "sisestage oma eesnimi"
getline enimi < "-"
print "sisestage oma perekonnanimi"
getline pnimi < "-"
print ( enimi == pnimi) ? "Teie ees- ja perekonnannimi on ühesugused"\
: "Teie ees- ja perekonnanimi ei ole ühesugused"
}

Rida jätkav kaigas peab olema viimane sümbol real.

Eeldades, et tekstifailis on kahel real vastavalt eesnimi ja perekonnanimi, käivitatakse skript selliselt

bash~$ cat tekst | skript.awk

Soovides skripti tööosa kasutada, tuleb kirjutada selline skript, kusjuures andmefailis on ühel real tühikuga eraldatud ees- ja perekonnanimi.

#!/usr/bin/awk -f
{ 
print ( $1 == $2 ) ? "Teie ees- ja perekonnannimi on ühesugused"\
: "Teie ees- ja perekonnanimi ei ole ühesugused"
}

Kui andmetega ridu on mitu, teostatakse kontroll iga reaga.

Faili lugemine ja kirjutamine

Loeme failist andmed ja kirjutame nummerdatud read teise faili.

#!/usr/bin/awk -f
BEGIN { i=1
while ( (getline rida < "lahteandmed" ) > 0 )
	{
		 print i ". " rida > "toodeldudandmed"
		 i++
	}
}

Korduse tingimuseks olev käsu getline lõppkood on nullist suurem seni, kuni midagi failist lähteandmeid lugeda on.

Süsteemi programmi väljundi lugemine ja sisendisse saatmine

Omistame muutuja aeg väärtuseks programmi date väljundi ning saadame muutuja aeg väärtuse programmi cat sisendisse.

#!/usr/bin/awk -f
BEGIN {
"date" | getline aeg
print "Süsteemi aeg on " aeg
print aeg | "cat"
}

Kirje ja väli

Awk käsitleb sisendit struktureerituna. Vaikimisi nimetakse kahe järjestikuse reavahetuste vahele jäävat kirjeks. Vaikimisi on jaotatud rida väljadeks tühikute või tabulatsioonimärkide kohalt.

Programmi tööosas saab väljade poole pöörduda muutujate $1, $2, $3, $4 jne abil. Muutuja $0 väärtuseks on terve kirje.

Sõltuvalt välja sisust saab teha nendega tehteid. Toome näite, kus leiame tulpadena esitatud lähteandmete ridade summad

bash~$ cat arvud
1 3 4 5
4 6 2 4
1 5 9 4
2 4 5 5

ning skript leia.summad.awk on seesugune

#!/usr/bin/awk -f
BEGIN   { print "Leiame ridade- ja kogusumma" }
            {  summa = $1 + $2 + $3 + $4
               print $1 " + " $2 " +  " $3 " +  " $4 " = " summa
               kogusumma = kogusumma + summa
            }
END     { print "Kogusumma = "  kogusumma }

Siin on esitatud kolm võimalikku skripti osa: algusosa, tööosa ja lõpuosa, kusjuures neile osadele vastavad käsud kirjutatakse loogadesse. Ühes osas kasutatud muutujatel on teises osas sama väärtus (nt kogusumma).

Käivitame skripti:

bash~$ cat arvud | leia.summad.awk
Leiame ridade -ja kogusumma
1 + 3 + 4 + 5 = 13
4 + 6 + 2 + 4 = 16
1 + 5 + 9 + 4 = 19
2 + 4 + 5 + 5 = 16
Kogusumma on 64

Kirje- ja väljaeraldusmärkide ümbermuutmine

Mõnel juhul on vajalik andmeid ridadeks ja väljadeks jagavaid märke muuta. Vastavalt saab muuta ka väljundis kasutatavaid rea- ja väljaeraldusmärke.

Seda saab teha näiteks defineerides skripti algusosas üle vastavate muutujate väärtused:

  • FS - sisendi välja eraldaja (ingl. k. field separator)
  • RS - sisendi kirje eraldaja (ingl. k. record separator)
  • OFS - väljundi välja eraldaja (ingl. k. output field separator)
  • ORS - väljundi kirje eraldaja (ingl. k. output record separator)

Kui välja eraldajaks on tühik, siis vastab see Awki vaikimisi toimimisele; sarnaselt on reavahetuse märgi ja kirje eraldajaga. Seades eraldajaks mõne teise sümboli, eraldatakse kirjet või välja selle sümboli kohalt. Kui eraldajaks on enam kui üks sümbol, käsitletakse eraldajat regulaaravaldisena.

Lisaks saab kasutada Awkiga seotud muutujaid

  • FILENAME - sisendfaili nimi
  • NF - käesoleva kirje väljade arv (ingl. k. number on fields)
  • NR - kirje absoluutne järjekorra number (ingl. k. number of the record)
  • FNR - kirje suhteline järjekorra number; on vajalik mitme sisendfaili kasutamisel

Toome näite nende muutujate kasutamise kohta. Algandmed on sellised

Priit
Elva
Jüri 15
tel. 15 123

Mart
Jüri
Elva 15
tel. 12 3 15

Peeter
Tartu
Telefoni 5
tel. 12 34 56

Nad soovitakse esitada nii, et ühte linna puutuv oleks ühel real, read oleks nummerdatud ning kõige lõppu kirjutataks algandmete faili nimi

$ ./skript.awk sisend.txt
1:Priit:Elva:Jüri 15:tel. 15 123
2:Mart:Jüri:Elva 15:tel. 12 3 15
3:Peeter:Tartu:Telefoni 5:tel. 12 34 56
andmefail: andmed

Sellise töö teeb ära selline skript

#!/usr/bin/awk -f
BEGIN {FS="\n"; RS="\n\n"; OFS=":"; ORS="\n"}
	{ print NR, $1, $2, $3, $4 }
END { OFS=" "; print "andmefail:", FILENAME }

Adresseerimine

Regulaaravaldistega saab määrata, millistele sisendi ridadele tööosa käsud rakenduvad. Toome näite, kus tegeldakse vaid Tartu linna temperatuuride ööpäevase keskmistamisega. Algandmed failis temperatuurid on sellised

linn   kp         6:00  12:00  18:00  24:00
Tartu  19/4/2000  13.6  15.1   15.8   14.0
Valga  19/4/2000  11.6  12.1   12.8   11.0
Tartu  20/4/2000  14.6  18.4   13.5   13.3
Valga  20/4/2000  13.4  15.7   15.1   14.3
Tartu  21/4/2000  16.6  21.1   19.3   17.1
Valga  21/4/2000  15.7  19.4   17.6   15.5
Tartu  22/4/2000  15.6  23.6   22.6   15.4
Valga  22/4/2000  13.5  16.2   14.7   15.3
Tartu  23/4/2000  17.3  19.4   21.4   12.3
Valga  23/4/2000  18.2  16.9   13.8   15.2

Skripti tööosa tegeleb vaid nende andmeridadega, mis klapivad regulaaravaldisega /Tartu/

#!/usr/bin/awk -f
BEGIN { print "Tartu õhutemperatuuri ööpäevane keskmine"
	printf ("Teostati neli mõõtmist: 6:00 12:00 18:00 24:00\n\n")
	print "koht   kuupäev   mõõtmistulemus"
	}
  /Tartu/ { keskmine = ( $3 + $4 + $5 + $6 ) / 4
            printf ("%s  %s  %2.2f\n", $1, $2, keskmine)
	  }
END   { printf ("\nMõõtmisi teostasid Priit ja Mart\n") }

Käivitamisel saame järgmise tulemuse

bash$ cat temperatuurid | tartu.keskm.temp.awk 
Tartu õhutemperatuuri ööpäevane keskmine
Teostati neli mõõtmist: 6:00 12:00 18:00 24:00

koht   kuupäev   mõõtmistulemus
Tartu  19/4/2000  14.62
Tartu  20/4/2000  14.95
Tartu  21/4/2000  18.52
Tartu  22/4/2000  19.30
Tartu  23/4/2000  17.60 

Mõõtmisi teostasid Priit ja Mart

Funktsiooni defineerimine

Funktsioonid defineeritakse väljaspool skripti osasid sellise süntaksi alusel

function funktsiooni.nimi (arg1, arg2, arg3) {
     laused
     return res1 res2
}

Esitame eelmise punkti viimase näite nii, et keskmine temperatuur leitakse funktsiooni abil

#!/usr/bin/awk -f
BEGIN { print "Tartu õhutemperatuuri ööpäevane keskmine"
	printf ("Teostati neli mõõtmist: 6:00 12:00 18:00 24:00\n\n")
	print "koht   kuupäev   mõõtmistulemus"
	}
function kesktemp (m1, m2, m3, m4) {
	keskmine = ( m1 + m2 + m3 + m4 ) / 4
	return keskmine
	}
  /Tartu/ { printf ("%s  %s  %2.2f\n", $1, $2, kesktemp($3, $4, $5, $6)) }

END   { printf ("\nMõõtmisi teostasid Priit ja Mart\n") }

Tööosa kasutamise näited

SQL dump faili tükeldamine

Olgu lähtepunktiks SQL dump fail sql.sql, mis sisaldab sarnaseid INSERT lauseid

 INSERT INTO inimesed VALUES (1, 'Mart', 'Kask', 38709067463);
 INSERT INTO inimesed VALUES (2, 'Priit', 'Kask', 38406087465);
 INSERT INTO inimesed VALUES (3, 'Laa', 'Lee', 38701304463);
 INSERT INTO inimesed VALUES (4, 'Koosinus', 'Pii', 31415926535);
 ...

Soovides jagada suure faili tükkideks nii, et iga tükk sisaldab 100 kirjet tuleb näiteks öelda

 $ awk 'BEGIN{RS="\nINSERT INTO inimesed ";} { i=i+1; j= i % 100 ; if ( j == 1 ) fi=fi+1; if ( i > 1 ) printf \
 ("%s", "INSERT INTO inimesed ") >> "fn_"fi; print >> "fn_"fi ; printf ("%d\n", i); system ("sleep 1") }' sql.sql

Skriptis on näha tööosas selliste konstruktsioonide kasutamist

  • aritmeetilised tehted ja võrdlused
  • väljundi formateermine ja faili suunamine
  • süsteemse käsu andmine

Tabulatsioonimärkidega edaldatud väljade info kättesaamine failist

$ awk 'BEGIN {FS="\t"; OFS="\t"} {print $1,$2}' large.txt > small.txt

Awkiga sisendi jooksev lugemine ja töötlemine

Jooksvalt töötav awk wrapper e vahekiht mis loeb ühelt töötavalt programmilt väljundit ja käitab vastavalt käske

Stardime programmi ja suuname ta väljundi wrapper skriptile, jätame mõlemad taustale tööle

/root/bin/programm | /root/bin/wrapper.sh &

Skript on ise selline, näiteskriptis loeb ta väljundist vaid kahte numbrit "1" ja "2". Esimesel juhul saadab ta maili generaator ok, teisel juhul väljastab teate rike ja saadab emaili generaator töötab.

#!/usr/bin/awk -f
{
if ( $3 != "1" )
        {
         print " systeem toimib"
         "echo \"generaator ok!\" | mail -s \"generaator ok!\" email@asdf.ee" | getline current_time
        }
else
        {
         print " rike"
          "echo \"generaator t22tab!\" | mail -s \"generaator t22tab!\" email@asdf.ee -c  email@asdf.ee"" | getline current_time
        } 
}

Lingid

http://www.ee.ucl.ac.uk/~hamed/misc/awk1line.txt Awk näidete kogumik

https://wiki.itcollege.ee/index.php/Awk

http://www.cyberciti.biz/faq/bash-scripting-using-awk/ hea lühike manual