Regulaaravaldised: Difference between revisions

From ICO wiki
Jump to navigationJump to search
Saus (talk | contribs)
Saus (talk | contribs)
No edit summary
 
(35 intermediate revisions by the same user not shown)
Line 1: Line 1:
Referaadi autor Sten Aus (rühm A22, õppeaasta 2012/2013). Töö esitamise aeg 18. november 2012.
[[Category: Operatsioonisüsteemide administreerimine ja sidumine ]]
[[Category: Operatsioonisüsteemide administreerimine ja sidumine ]]


= Eellugu =
= Referaat =
See referaat on valminud õppeaine operatsioonisüsteemide administreerimine ja sidumine (I233) raames 2012/2013 õppeaastal.
See referaat on valminud õppeaine operatsioonisüsteemide administreerimine ja sidumine (I233) raames 2012/2013 õppeaastal.
Töö lõplikuks autoriks on Sten Aus (rühm A22), aluseks on võetud Carolys Kallas (rühm A22) referaat aastast 2011. Kuna referaat praktiliselt koosneski ühest lausest, siis viide algsele teosele on eemaldatud. Seda on võimalik vaadata selle lehe Wiki ajaloost.
Töö lõplikuks autoriks on Sten Aus (rühm A22), aluseks on võetud Carolys Kallas (rühm A22) referaat aastast 2011. Kuna referaat praktiliselt koosneski ühest lausest, siis viide algsele teosele on eemaldatud. Seda on võimalik vaadata selle lehe Wiki ajaloost.


Referaadi teema on valitud autori poolt 29. oktoobril 2012. aastal.
Referaadi teema on valitud autori poolt 29. oktoobril 2012. aastal.
{|style="background:#FAEBD7; border:1px solid #BABABA; width:100%; margin:3px;" align=centre
| | '''Referaadis toodud failide ja koodide näited on esitatud rohelisel taustal kastidega. Juhul kui on tegemist mingi tähelepanu nõudva või soovitusega, on tegemist punakas-roosade kastidega.'''
|}


= Sissejuhatus regulaaravaldistesse =
= Sissejuhatus regulaaravaldistesse =
Regulaaravaldis ''(regular expression; regexp)'' on olemuselt ''string'' (elemendi- või märgijada [http://vallaste.ee/sona.asp?Type=UserId&otsing=495]), mis sisaldab endas teisi stringe, mis on teatud korra- ja reeglipäraselt üksteise järel ritta seatud.
Regulaaravaldis ''(regular expression; regexp)[http://en.wikipedia.org/wiki/Regular_expression]'' on olemuselt ''string'' (elemendi- või märgijada [http://vallaste.ee/sona.asp?Type=UserId&otsing=495]), mis sisaldab endas teisi stringe, mis on teatud korra- ja reeglipäraselt üksteise järel ritta seatud.
Regulaaravaldisi kasutatakse paljudes kohtades - peamiselt küll UNIX-i laadsetes süsteemides, aga näiteks ka programmeerimiskeeltes nagu näiteks PHP, Perl jt. [http://www.cyberciti.biz/tips/unix-linux-regular-expressions-regex-howto-tutorial.html]
Regulaaravaldisi kasutatakse paljudes kohtades - peamiselt küll UNIX-i laadsetes süsteemides, aga näiteks ka programmeerimiskeeltes nagu näiteks PHP, Perl jt. [http://www.cyberciti.biz/tips/unix-linux-regular-expressions-regex-howto-tutorial.html]


Line 16: Line 22:


* [] - märgivalik või vahemik ('''näide 1:''' m[aeo]kk tähendab sõnu makk, mekk, mokk; '''näide 2:''' versioon[01-03] tähendab versioon01, versioon02, versioon03)
* [] - märgivalik või vahemik ('''näide 1:''' m[aeo]kk tähendab sõnu makk, mekk, mokk; '''näide 2:''' versioon[01-03] tähendab versioon01, versioon02, versioon03)
* . - tähemärk (näide: s.en tähendab seen, s@en, s!en, saen, ... ) ''NB! tähemärke võib ka mitu tükki järjest olla, sellisel juhul tuleb lihtsalt nii mitu punkti lisada, kui mitu tähemärki on vaja''
* . - tähemärk ('''näide:''' s.en tähendab seen, s@en, s!en, saen, ... ) ''NB! tähemärke võib ka mitu tükki järjest olla, sellisel juhul tuleb lihtsalt nii mitu punkti lisada, kui mitu tähemärki on vaja''
* ^ - rea algus (näide: kui kasutada grep rakendusega ''^bat'' tingimust mingil failil, siis otsitakse selle faili iga rea alguses esinevat fraasi "bat")
* ^ - rea algus ('''näide:''' kui kasutada grep rakendusega ''^bat'' tingimust mingil failil, siis otsitakse selle faili iga rea alguses esinevat fraasi "bat")
* $ - rea lõpp (näide: kui kasutada grep rakendusega ''sti$'' tingimust mingil failil, siis otsitakse selle faili iga rea lõpust esinevat fraasi "sti")
* $ - rea lõpp ('''näide:''' kui kasutada grep rakendusega ''sti$'' tingimust mingil failil, siis otsitakse selle faili iga rea lõpust esinevat fraasi "sti")
* * - suvaline sümbol (suvaline arv sümboleid (0 kuni lõpmatus)) ('''näide 1:''' au* tähendab austraalia, austria, ...; ehk siis tärnist eelnevad sümbolid jäetakse alles; '''näide 2:''' find *.* leiab kõik failid, kus sees on punkt)
* * - suvaline sümbol (suvaline arv sümboleid (0 kuni lõpmatus)) ('''näide 1:''' au* tähendab austraalia, austria, ...; ehk siis tärnist eelnevad sümbolid jäetakse alles; '''näide 2:''' find *.* leiab kõik failid, kus sees on punkt)
* \ - sellele sümboline järgnevat metasümbolit võetakse kui tavalist sümbolit (näide: find \^ tähendab, et otsitakse failinime seest ^ märki, mitte ei tähenda see rea alguse sümbolit)
* \ - sellele sümboline järgnevat metasümbolit võetakse kui tavalist sümbolit ('''näide:''' find \^ tähendab, et otsitakse failinime seest ^ märki, mitte ei tähenda see rea alguse sümbolit)


== Laiendatud ==
== Laiendatud sümbolid ==
* + - pluss: üks või enam vasakul olevad sümbolit
* + - pluss: üks või enam vasakul olevad sümbolit
* ? - küsimärk: null või üks vasakul olevat sümbolit
* ? - küsimärk: null või üks vasakul olevat sümbolit
Line 28: Line 34:
* () - sulud: grupeerib regulaaravaldisi
* () - sulud: grupeerib regulaaravaldisi
* {n,m} - loogad: mitu eelnevat sümbolit
* {n,m} - loogad: mitu eelnevat sümbolit
Laiendatud sümbolid on koostatud kasutades EENet lehel leiduvat õpetust.[http://kuutorvaja.eenet.ee/programmeerimine/regulaaravaldised.html]


= Regulaaravaldise koostamine =
= Regulaaravaldise koostamine =


''Regulaaravaldiste kasutamiseks (koostamiseks) pole vaja administraatoriõiguseid. Seda loomulikult juhul, kui te ei soovi tegeleda failidega (kohvritega), millele teil õiguseid pole.''
{|style="background:#FAEBD7; border:1px solid #BABABA; width:100%; margin:3px;" align=centre
| | Regulaaravaldiste kasutamiseks (koostamiseks) pole vaja administraatoriõiguseid. Seda loomulikult juhul, kui te ei soovi tegeleda failidega (kohvritega), millele teil õiguseid pole.
|}


Antud punkti läbimiseks tuleb väga kasuks '''suunamise''' baasteadmiste omandatus. Kui seda pole, siis võib alljärgneva koodi lugemine osutuda keerulisemaks. Järgmises punktis anname väga lühikese ülevaate, et ühtlustada taset. Aga kuna see on selle juhendi skoobist väljas, siis me sellel teemal väga pikalt ei peatu.
Antud punkti läbimiseks tuleb väga kasuks '''suunamise''' baasteadmiste omandatus. Kui seda pole, siis võib alljärgneva koodi lugemine osutuda keerulisemaks. Järgmises punktis anname väga lühikese ülevaate, et ühtlustada taset. Aga kuna see on selle juhendi skoobist väljas, siis me sellel teemal väga pikalt ei peatu.
Line 49: Line 59:
== Linuxi utiliit find ==
== Linuxi utiliit find ==
Oleme kodukaustas, meid huvitab esialgu kõik "u"-ga algavad failid ja kaustad. Kasutan '''find''' jaoks parameetrit '''-iname''', mis garanteerib, et meie otsingu puhul ei arvestata suur- ega väiketähtede erinevust. Rohkem infot find'i parameetrite kohta leiab, kui kasutate käsku '''man find'''
Oleme kodukaustas, meid huvitab esialgu kõik "u"-ga algavad failid ja kaustad. Kasutan '''find''' jaoks parameetrit '''-iname''', mis garanteerib, et meie otsingu puhul ei arvestata suur- ega väiketähtede erinevust. Rohkem infot find'i parameetrite kohta leiab, kui kasutate käsku '''man find'''
{|style="background:#FAEBD7; border:1px solid #BABABA; width:500px; margin:3px;" align=centre
{|style="background:#a7f0d2; border:1px solid #BABABA; width:500px; margin:3px;" align=centre
| style="padding:0px 0px 0px 80px; font-family: courier; font-size:10pt;" | find -iname "u*"  
| style="padding:0 0 0 30px; font-family: courier; font-size:10pt;" | find -iname "u*"  
|}
|}


Otsime parameetri "u[akn]*" järgi.
Otsime parameetri "u[akn]*" järgi.
''PS! Antud otsingutingimus eeldab, et sellised failid on teie kohvris olemas. Failid on loodud näitlikkuse jaoks. Mingit sisu/otstarvet neil pole.''
 
{|style="background:#FAEBD7; border:1px solid #BABABA; width:500px; margin:3px;" align=centre
{|style="background:#FAEBD7; border:1px solid #BABABA; width:100%; margin:3px;" align=centre
| style="padding:0px 0px 0px 80px; font-family: courier; font-size:10pt;" | find -iname "u[akn]*"  
|  | ''PS! Antud otsingutingimus eeldab, et sellised failid on teie kohvris olemas. Failid on loodud näitlikkuse jaoks. Mingit sisu/otstarvet neil pole.''
|}
 
{|style="background:#a7f0d2; border:1px solid #BABABA; width:500px; margin:3px;" align=centre
| style="padding:0 0 0 30px; font-family: courier; font-size:10pt;" | find -iname "u[akn]*"  
|}
|}
Antud tingimus otsib failid ja kohvrid, mis algavad "ua", "uk" või "un" kombinatsiooniga. See, mis failinimes edasi on, ei oma tähtsust.
Antud tingimus otsib failid ja kohvrid, mis algavad "ua", "uk" või "un" kombinatsiooniga. See, mis failinimes edasi on, ei oma tähtsust.


Kirjutame selle sama otsingitulemuse kuskile faili.
Kirjutame selle sama otsingitulemuse kuskile faili.
{|style="background:#FAEBD7; border:1px solid #BABABA; width:500px; margin:3px;" align=centre
{|style="background:#a7f0d2; border:1px solid #BABABA; width:500px; margin:3px;" align=centre
| style="padding:0px 0px 0px 80px; font-family: courier; font-size:10pt;" | find -iname "u[akn]*" > otsingutulemus.txt
| style="padding:0 0 0 30px; font-family: courier; font-size:10pt;" | find -iname "u[akn]*" > otsingutulemus.txt
|}
|}
Tundub, et midagi ei toimunud (kuna ekraanile midagi ju ei tulnud). Seda sellepärast, et kasutasime suunamist ja kirjutasime tulemuse faili (mis muidu pidi standardväljundisse tulema). Kui kasutada '''ls''' käsku, siis näeme, et tekkinud on uus fail nimega "otsingutulemus.txt". Kui see avada näiteks '''nano''' utiliidiga, siis leiame sealt seest otsingutulemuse.
Tundub, et midagi ei toimunud (kuna ekraanile midagi ju ei tulnud). Seda sellepärast, et kasutasime suunamist ja kirjutasime tulemuse faili (mis muidu pidi standardväljundisse tulema). Kui kasutada '''ls''' käsku, siis näeme, et tekkinud on uus fail nimega "otsingutulemus.txt". Kui see avada näiteks '''nano''' utiliidiga, siis leiame sealt seest otsingutulemuse.
Line 70: Line 84:


Näitlikkuse jaoks loome faili '''test''', kuhu kirjutame järgnevad read.
Näitlikkuse jaoks loome faili '''test''', kuhu kirjutame järgnevad read.
{|style="background:#FAEBD7; border:1px solid #BABABA; width:500px; margin:3px;" align=centre
{|style="background:#a7f0d2; border:1px solid #BABABA; width:500px; margin:3px;" align=centre
| style="padding:0px 0px 0px 80px; font-family: courier; font-size:10pt;" | 1912
| style="padding:0 0 0 30px; font-family: courier; font-size:10pt;" | 1912


minu rida
minu rida
Line 96: Line 110:
Kasutame '''grep''' utiliiti, et leida antud failist mingi fraas. Grep süntaksiga on võimalik tutvuda kasutades käsku '''man grep'''.
Kasutame '''grep''' utiliiti, et leida antud failist mingi fraas. Grep süntaksiga on võimalik tutvuda kasutades käsku '''man grep'''.


{|style="background:#FAEBD7; border:1px solid #BABABA; width:500px; margin:3px;" align=centre
{|style="background:#a7f0d2; border:1px solid #BABABA; width:500px; margin:3px;" align=centre
| style="padding:0px 0px 0px 80px; font-family: courier; font-size:10pt;" | grep uued test
| style="padding:0 0 0 30px; font-family: courier; font-size:10pt;" | grep uued test
|}
|}


Leiame protsesitabelist üles kõik protsessid, mis kuuluvad kasutajale root ja lisame selle tulemuse juurde faili test.
Leiame protsesitabelist üles kõik protsessid, mis kuuluvad kasutajale root ja lisame selle tulemuse juurde faili test.


{|style="background:#FAEBD7; border:1px solid #BABABA; width:500px; margin:3px;" align=centre
{|style="background:#a7f0d2; border:1px solid #BABABA; width:500px; margin:3px;" align=centre
| style="padding:0px 0px 0px 80px; font-family: courier; font-size:10pt;" | ps -ef | grep ^root >> test
| style="padding:0 0 0 30px; font-family: courier; font-size:10pt;" | ps -ef | grep ^root >> test
|}
|}


Grep utiliidi üks hea võimalus on see, et parameetriga ''-f'' saab anda mustri, mille järgi otsitakse, ette hoopis mingist failist. Oletame, et meie muster ''bemm'' asub failis ''muster''. Sellisel juhul kood peaks nägema välja järgnev.
Grep utiliidi üks hea võimalus on see, et parameetriga ''-f'' saab anda mustri, mille järgi otsitakse, ette hoopis mingist failist. Oletame, et meie muster ''bemm'' asub failis ''muster''. Sellisel juhul kood peaks nägema välja järgnev.


{|style="background:#FAEBD7; border:1px solid #BABABA; width:500px; margin:3px;" align=centre
{|style="background:#a7f0d2; border:1px solid #BABABA; width:500px; margin:3px;" align=centre
| style="padding:0px 0px 0px 80px; font-family: courier; font-size:10pt;" | grep -f muster test
| style="padding:0 0 0 30px; font-family: courier; font-size:10pt;" | grep -f muster test
|}
 
== Linuxi utiliit sed ==
Regulaaravaldisi kasutatakse veel ka automaatseks tekstitöötluseks. St et kasutaja (inimese) osavõtt sellest protsessist on vajalik ainult regulaaravaldise kirjutamiseks - ülejäänud teeb automaatselt ära programm '''sed''' - inglise keeles ''stream editor'', eesti keeles voo muutja.[http://kuutorvaja.eenet.ee/programmeerimine/sed/sed.html]
 
{|style="background:#FAEBD7; border:1px solid #BABABA; width:100%; margin:3px;" align=centre
|  | ''Kuna sed pole kasutusel tavakasutaja igapäeva töös [http://www.eenet.ee/EENet/assets/docs/abs/sed.html], siis peatume selles punktis vaid peamistel tõdedel.''
 
''Juhin tähelepanu sellele, et automaatselt ei salvestata faili üle, vaid sed väljund kuvatakse standardväljundisse. Et fail automaatselt üle salvestataks on vaja kasutada suunamist (kusjuures seda suunamist, mis loob faili või kustutab selle üle. Vastasel juhul kirjutatakse faili juurde ja säilivad vanad andmed (andmeid saab topelt).
Samuti tasub meeles pidada, et sed ei saa üle kirjutada seda sama faili, millega tööd tehakse (sisendfaili ehk faili, kust loetakse sed sisend). Tulemuseks on vaja luua uus fail. Küll aga saab üle kirjutada juba olemasolevat faili.''
|}
 
Antud utiliidi puhul kasutame näideteks faili '''linnad''', kuhu sisse kirjutame järgnevad read:
{|style="background:#a7f0d2; border:1px solid #BABABA; width:500px; margin:3px;" align=centre
| style="padding:0 0 0 30px; font-family: courier; font-size:10pt;" | tallinn
 
tartu
 
pärnu
 
viljandi
 
narva
 
jõhvi
 
valga
 
võhma
 
asfae
 
|}
 
Miks viimane rida on asfae? Küll varsti saame teada. ;)
 
=== Süntaks ja sed võimalused ===
 
 
{|style="background:#FAEBD7; border:1px solid #BABABA; width:100%; margin:3px;" align=centre
|  | ''sed utiliiti kasutades soovitan tingimused kirjutada ülakomade \'\' vahele. Seda sellepärast, et programmi tööd (ja oma elu) lihtsustada. :) Kui proovite mõne keerukama (tegelikult piisab isegi kustutamise (vt allpool) käsku kasutades) regulaaravaldise kirjutamisel mitte kasutada ülakomasid, siis võite väga kiiresti lõpetada suure errori-kuhja all - teadmata miks.''
|}
 
==== Ridade kuvamine ====
 
Failist ridade kuvamiseks tuleb kasutada käsku '''q'''.
 
Alljärgnev kood kuvab meile failist "linnad" esimese rea.
{|style="background:#a7f0d2; border:1px solid #BABABA; width:500px; margin:3px;" align=centre
| style="padding:0 0 0 30px; font-family: courier; font-size:10pt;" | sed '1q' linnad
|}
 
Alljärgnev kood kuvab meile failist "linnad" kõik read, peale esimese.
{|style="background:#a7f0d2; border:1px solid #BABABA; width:500px; margin:3px;" align=centre
| style="padding:0 0 0 30px; font-family: courier; font-size:10pt;" | sed '1!q' linnad
|}
 
==== Kustutamine ====
 
Failist kustutamiseks tuleb kasutada käsku '''d'''.
 
Soovime näiteks kustutada failist "linnad" kolmanda rea. Selleks kasutame käsku.
{|style="background:#a7f0d2; border:1px solid #BABABA; width:500px; margin:3px;" align=centre
| style="padding:0 0 0 30px; font-family: courier; font-size:10pt;" | sed '3d' linnad
|}
 
Kui soovitakse kustutada kõik, peale mingi rea, siis on vaja kasutada hüüumärki reanumbri järel. Näiteks kustutame kõik read peale kolmanda.
{|style="background:#a7f0d2; border:1px solid #BABABA; width:500px; margin:3px;" align=centre
| style="padding:0 0 0 30px; font-family: courier; font-size:10pt;" | sed '3!d' linnad
|}
 
==== Asendamine ====
 
Mingi rea (stringi) asendamiseks on vaja kasutada sedi käsku '''s'''.
 
Asendades näiteks ülal loodud failis asfae sõnaga Kuressaare
{|style="background:#a7f0d2; border:1px solid #BABABA; width:500px; margin:3px;" align=centre
| style="padding:0 0 0 30px; font-family: courier; font-size:10pt;" | sed 's/asfae/Kuresaare/' linnad
|}
 
* '''s''' tähendab asendamist (ingl k. ''substitute'')
* '''asfae''' - osa, mida soovitakse asendada
* ''' Kuresaare''' - osa, millega asendatakse
 
{|style="background:#FAEBD7; border:1px solid #BABABA; width:100%; margin:3px;" align=centre
|  | Windowsis annaks võrrelda seda käsku kui ''"search and replace"'' ehk "otsi ja asenda".
|}
 
==== Transformeerimine ====
 
Transformeerimist kasutatakse mingi stringi üleviimiseks kindlale kujule. Näiteks kogu string väiketähtedeks, suurtähtedeks. Selleks kasutatakse sedi käsku '''y'''.
 
{|style="background:#FAEBD7; border:1px solid #BABABA; width:100%; margin:3px;" align=centre
|  | ''Juhin tähelepanu, et asendamisel asendatakse etteantud tingimuses tähed igal juhul - olenemata kas nad esinevad antud järjekorras või mitte!''
|}
 
Asendame esialgu kõik väiketähed "a" ja "v" vastavalt suurtähtedega "A" ja "V".
 
{|style="background:#a7f0d2; border:1px solid #BABABA; width:500px; margin:3px;" align=centre
| style="padding:0 0 0 30px; font-family: courier; font-size:10pt;" | sed 'y/av/AV/' linnad
|}
 
Väljund on üsna kole, või mis? :)
 
==== Lõpetamine ====
 
Sed ei pea ilmtingimata töötama kuni faili lõpuni. Kasutades käsku '''q''' saame määrata tingimuse, millal sed oma töö lõpetab.
 
Olgu meie näiteks tingimuseks "a" tähe leidumine.
 
{|style="background:#a7f0d2; border:1px solid #BABABA; width:500px; margin:3px;" align=centre
| style="padding:0 0 0 30px; font-family: courier; font-size:10pt;" | sed '/a/q' linnad
|}
 
Paremini sobiks näide, kus lõpetatakse sedi töö tühja rea leidmisel. Muudame kõigepealt oma faili "linnad" nii, et seal oleks pärast tartu rida üks tühi rida. Nüüd käivitame järgneva koodi.
 
{|style="background:#a7f0d2; border:1px solid #BABABA; width:500px; margin:3px;" align=centre
| style="padding:0 0 0 30px; font-family: courier; font-size:10pt;" | sed '/^$/q' linnad
|}
|}
Nagu väljundist näeme, lõpetati programmi töö, kui tühi rida leiti. :)
==== Skriptide kasutamine ====
Sedi tööd on võimalik efektiivsemaks ja mugavamaks teha, kui kasutada skripte. Skripti sisse on võimalik kirjutada järjestik osa koode, mis käivitatakse koos sediga ja tehakse ilminemise järjekorras läbi. Nii on võimalik nt üles leida read, mis on tühjad, kustutada need ja teha kõik rea algused suurte tähtedega jne. Ja seda kõike ühe korraga. :)
Skriptifaili etteandmiseks on vaja kasutada käsku '''-f'''
Üldjoontes peaks käsk välja nägema järgnev:
{|style="background:#a7f0d2; border:1px solid #BABABA; width:500px; margin:3px;" align=centre
| style="padding:0 0 0 30px; font-family: courier; font-size:10pt;" | sed -f skriptifail linnad
|}
=== Näide 1 ===
Kui lõime oma faili "linnad", kirjutasime sinna koleda stringi "asfae". Kasutame ära õpitud omadusi ja eemaldame selle rea, kusjuures otsides seda stringi ja kirjutame selle asemele ilusa linna nimega Haapsalu. Ja lõpetuseks salvestame uue tulemuse faili linnad_2.
{|style="background:#a7f0d2; border:1px solid #BABABA; width:500px; margin:3px;" align=centre
| style="padding:0 0 0 30px; font-family: courier; font-size:10pt;" | sed 's/^asfae$/Haapsalu/' linnad > linnad_2
|}
=== Näide 2 ===
Teeme näite kasutades faili asendaja. Sinna sisse kirjutame järgmise koodi.
Asendaja fail hoiab endas järgmisi käske. Väiketähed "a-z", mis esinevad rea alguses asendatakse vastavate suurtähtedega "A-Z". Hiljem asendatakse string "Asfae" stringiga "Haapsalu".
{|style="background:#a7f0d2; border:1px solid #BABABA; width:500px; margin:3px;" align=centre
| style="padding:0 0 0 30px; font-family: courier; font-size:10pt;" | # skripti eesm2rgiks on asendada k6ik v2iket2hega algavad read suurt2htedega
s/^a/A/
s/^b/B/
s/^c/C/
s/^d/D/
s/^e/E/
s/^f/F/
s/^g/G/
s/^h/H/
s/^i/I/
s/^j/J/
s/^k/K/
s/^l/L/
s/^m/M/
s/^n/N/
s/^o/O/
s/^p/P/
s/^q/Q/
s/^r/R/
s/^s/S/
s/^t/T/
s/^u/U/
s/^v/V/
s/^x/X/
s/^y/Y/
s/^z/Z/
\# asendame koleda stringi asfae stringiga Haapsalu
s/Asfae/Haapsalu/
|}
Nüüd käivitame käsu
{|style="background:#a7f0d2; border:1px solid #BABABA; width:500px; margin:3px;" align=centre
| style="padding:0 0 0 30px; font-family: courier; font-size:10pt;" | sed -f asendaja linnad > linnad_2
|}
Ja tulemuseks on "linnad_2" fail, mille sisu toome siinkohal välja:
{|style="background:#a7f0d2; border:1px solid #BABABA; width:500px; margin:3px;" align=centre
| style="padding:0 0 0 30px; font-family: courier; font-size:10pt;" | Tallinn
Tartu
Pärnu
Viljandi
Narva
Jõhvi
Valga
Võhma
Haapsalu
|}
= Kokkuvõte =
Regulaaravaldised võivad teha UNIXi maailmas teie elu mitmeid kordi lihtsamaks. Kõige tähtsam on tunda õiget süntaksi ning teada, mida te teete. Kindlasti tasub tähtsate failide puhul teha varukoopiaid ja esialgu proovida test-failide peal oma kood läbi. Seda sellepärast, et ka siin toodud näited on algelised ja kindlasti mitte lõpliku teadmiste omandamiseks piisavad.
Regulaaravaldisi kasutatakse väga palju UNIXi maailmas, aga ka erinevates programmeerimiskeeltes on nad väga valjalikud ja suured abimehed.
Antud juhendis (referaadis) keskendusime UNIXi kolmele käsurea programmile - find, grep ja sed. See nimekiri pole loomulikult lõplik ja soovitan kõigil, kel vähegi huvi selle vastu on, edasi lugeda. Internet on suur ja lai. :)


= Kasutatud kirjandus =
= Kasutatud kirjandus =
Line 118: Line 375:
http://www.cyberciti.biz/tips/unix-linux-regular-expressions-regex-howto-tutorial.html
http://www.cyberciti.biz/tips/unix-linux-regular-expressions-regex-howto-tutorial.html


http://www.eenet.ee/EENet/assets/docs/abs/mall.html#regexp


''(Carolys materjal)''
http://kuutorvaja.eenet.ee/programmeerimine/regulaaravaldised.html


UNIX juhend - Regulaaravaldised http://www.eenet.ee/EENet/assets/docs/abs/mall.html#regexp
http://en.wikipedia.org/wiki/Regular_expression


Kuutõrvaja http://kuutorvaja.eenet.ee/programmeerimine/regulaaravaldised.html
http://kuutorvaja.eenet.ee/programmeerimine/sed/sed.html


Regular expression http://en.wikipedia.org/wiki/Regular_expression
http://www.eenet.ee/EENet/assets/docs/abs/sed.html

Latest revision as of 11:58, 19 November 2012

Referaadi autor Sten Aus (rühm A22, õppeaasta 2012/2013). Töö esitamise aeg 18. november 2012.

Referaat

See referaat on valminud õppeaine operatsioonisüsteemide administreerimine ja sidumine (I233) raames 2012/2013 õppeaastal. Töö lõplikuks autoriks on Sten Aus (rühm A22), aluseks on võetud Carolys Kallas (rühm A22) referaat aastast 2011. Kuna referaat praktiliselt koosneski ühest lausest, siis viide algsele teosele on eemaldatud. Seda on võimalik vaadata selle lehe Wiki ajaloost.

Referaadi teema on valitud autori poolt 29. oktoobril 2012. aastal.

Referaadis toodud failide ja koodide näited on esitatud rohelisel taustal kastidega. Juhul kui on tegemist mingi tähelepanu nõudva või soovitusega, on tegemist punakas-roosade kastidega.

Sissejuhatus regulaaravaldistesse

Regulaaravaldis (regular expression; regexp)[1] on olemuselt string (elemendi- või märgijada [2]), mis sisaldab endas teisi stringe, mis on teatud korra- ja reeglipäraselt üksteise järel ritta seatud. Regulaaravaldisi kasutatakse paljudes kohtades - peamiselt küll UNIX-i laadsetes süsteemides, aga näiteks ka programmeerimiskeeltes nagu näiteks PHP, Perl jt. [3]

Esialgu võib regulaaravaldiste teema tunduda algajale väga keeruline ja raske, kuid fundamentaalteadmiste omandamisel on sellest tööriistast väga palju kasu.

Regulaaravaldistes kasutatavad sümbolid

  • [] - märgivalik või vahemik (näide 1: m[aeo]kk tähendab sõnu makk, mekk, mokk; näide 2: versioon[01-03] tähendab versioon01, versioon02, versioon03)
  • . - tähemärk (näide: s.en tähendab seen, s@en, s!en, saen, ... ) NB! tähemärke võib ka mitu tükki järjest olla, sellisel juhul tuleb lihtsalt nii mitu punkti lisada, kui mitu tähemärki on vaja
  • ^ - rea algus (näide: kui kasutada grep rakendusega ^bat tingimust mingil failil, siis otsitakse selle faili iga rea alguses esinevat fraasi "bat")
  • $ - rea lõpp (näide: kui kasutada grep rakendusega sti$ tingimust mingil failil, siis otsitakse selle faili iga rea lõpust esinevat fraasi "sti")
  • * - suvaline sümbol (suvaline arv sümboleid (0 kuni lõpmatus)) (näide 1: au* tähendab austraalia, austria, ...; ehk siis tärnist eelnevad sümbolid jäetakse alles; näide 2: find *.* leiab kõik failid, kus sees on punkt)
  • \ - sellele sümboline järgnevat metasümbolit võetakse kui tavalist sümbolit (näide: find \^ tähendab, et otsitakse failinime seest ^ märki, mitte ei tähenda see rea alguse sümbolit)

Laiendatud sümbolid

  • + - pluss: üks või enam vasakul olevad sümbolit
  • ? - küsimärk: null või üks vasakul olevat sümbolit
  • | - toru: eelnev või järgnev regulaaravaldis
  • () - sulud: grupeerib regulaaravaldisi
  • {n,m} - loogad: mitu eelnevat sümbolit

Laiendatud sümbolid on koostatud kasutades EENet lehel leiduvat õpetust.[4]

Regulaaravaldise koostamine

Regulaaravaldiste kasutamiseks (koostamiseks) pole vaja administraatoriõiguseid. Seda loomulikult juhul, kui te ei soovi tegeleda failidega (kohvritega), millele teil õiguseid pole.

Antud punkti läbimiseks tuleb väga kasuks suunamise baasteadmiste omandatus. Kui seda pole, siis võib alljärgneva koodi lugemine osutuda keerulisemaks. Järgmises punktis anname väga lühikese ülevaate, et ühtlustada taset. Aga kuna see on selle juhendi skoobist väljas, siis me sellel teemal väga pikalt ei peatu.

Suunamine (teemaväline)

Mõisted

  • standardsisend - klaviatuur
  • standarväljund - kuvar (ekraan)

Suunamise süntaks

  • > - suunab standardväljundi faili (loob selle või kirjutab üle)
  • >> - suunab standardväljundi faili (lisab olemasolevale sisule)
  • < - loeb näidatud faili standardsisendisse
  • << - loeb järgnevad read standardsisendisse

Linuxi utiliit find

Oleme kodukaustas, meid huvitab esialgu kõik "u"-ga algavad failid ja kaustad. Kasutan find jaoks parameetrit -iname, mis garanteerib, et meie otsingu puhul ei arvestata suur- ega väiketähtede erinevust. Rohkem infot find'i parameetrite kohta leiab, kui kasutate käsku man find

find -iname "u*"

Otsime parameetri "u[akn]*" järgi.

PS! Antud otsingutingimus eeldab, et sellised failid on teie kohvris olemas. Failid on loodud näitlikkuse jaoks. Mingit sisu/otstarvet neil pole.
find -iname "u[akn]*"

Antud tingimus otsib failid ja kohvrid, mis algavad "ua", "uk" või "un" kombinatsiooniga. See, mis failinimes edasi on, ei oma tähtsust.

Kirjutame selle sama otsingitulemuse kuskile faili.

find -iname "u[akn]*" > otsingutulemus.txt

Tundub, et midagi ei toimunud (kuna ekraanile midagi ju ei tulnud). Seda sellepärast, et kasutasime suunamist ja kirjutasime tulemuse faili (mis muidu pidi standardväljundisse tulema). Kui kasutada ls käsku, siis näeme, et tekkinud on uus fail nimega "otsingutulemus.txt". Kui see avada näiteks nano utiliidiga, siis leiame sealt seest otsingutulemuse.

Linuxi utiliit grep

Grep on üks enimkasutatavaid utiliite, kus saab väga efektiivselt kasutada regulaaravaldisi. Kui find on kasutusel sellejaoks, et otsida faili- või kohvrinimesid, siis grep on kasutusel, et otsida failide seest mingit fraasi, osa vms.

Näitlikkuse jaoks loome faili test, kuhu kirjutame järgnevad read.

1912

minu rida

teine rida

19234 23 s.

maiu

on

piimaauto

bla bla

veel midagi

mul on bemmil

uued kummid

Kasutame grep utiliiti, et leida antud failist mingi fraas. Grep süntaksiga on võimalik tutvuda kasutades käsku man grep.

grep uued test

Leiame protsesitabelist üles kõik protsessid, mis kuuluvad kasutajale root ja lisame selle tulemuse juurde faili test.

ps -ef | grep ^root >> test

Grep utiliidi üks hea võimalus on see, et parameetriga -f saab anda mustri, mille järgi otsitakse, ette hoopis mingist failist. Oletame, et meie muster bemm asub failis muster. Sellisel juhul kood peaks nägema välja järgnev.

grep -f muster test

Linuxi utiliit sed

Regulaaravaldisi kasutatakse veel ka automaatseks tekstitöötluseks. St et kasutaja (inimese) osavõtt sellest protsessist on vajalik ainult regulaaravaldise kirjutamiseks - ülejäänud teeb automaatselt ära programm sed - inglise keeles stream editor, eesti keeles voo muutja.[5]

Kuna sed pole kasutusel tavakasutaja igapäeva töös [6], siis peatume selles punktis vaid peamistel tõdedel.

Juhin tähelepanu sellele, et automaatselt ei salvestata faili üle, vaid sed väljund kuvatakse standardväljundisse. Et fail automaatselt üle salvestataks on vaja kasutada suunamist (kusjuures seda suunamist, mis loob faili või kustutab selle üle. Vastasel juhul kirjutatakse faili juurde ja säilivad vanad andmed (andmeid saab topelt). Samuti tasub meeles pidada, et sed ei saa üle kirjutada seda sama faili, millega tööd tehakse (sisendfaili ehk faili, kust loetakse sed sisend). Tulemuseks on vaja luua uus fail. Küll aga saab üle kirjutada juba olemasolevat faili.

Antud utiliidi puhul kasutame näideteks faili linnad, kuhu sisse kirjutame järgnevad read:

tallinn

tartu

pärnu

viljandi

narva

jõhvi

valga

võhma

asfae

Miks viimane rida on asfae? Küll varsti saame teada. ;)

Süntaks ja sed võimalused

sed utiliiti kasutades soovitan tingimused kirjutada ülakomade \'\' vahele. Seda sellepärast, et programmi tööd (ja oma elu) lihtsustada. :) Kui proovite mõne keerukama (tegelikult piisab isegi kustutamise (vt allpool) käsku kasutades) regulaaravaldise kirjutamisel mitte kasutada ülakomasid, siis võite väga kiiresti lõpetada suure errori-kuhja all - teadmata miks.

Ridade kuvamine

Failist ridade kuvamiseks tuleb kasutada käsku q.

Alljärgnev kood kuvab meile failist "linnad" esimese rea.

sed '1q' linnad

Alljärgnev kood kuvab meile failist "linnad" kõik read, peale esimese.

sed '1!q' linnad

Kustutamine

Failist kustutamiseks tuleb kasutada käsku d.

Soovime näiteks kustutada failist "linnad" kolmanda rea. Selleks kasutame käsku.

sed '3d' linnad

Kui soovitakse kustutada kõik, peale mingi rea, siis on vaja kasutada hüüumärki reanumbri järel. Näiteks kustutame kõik read peale kolmanda.

sed '3!d' linnad

Asendamine

Mingi rea (stringi) asendamiseks on vaja kasutada sedi käsku s.

Asendades näiteks ülal loodud failis asfae sõnaga Kuressaare

sed 's/asfae/Kuresaare/' linnad
  • s tähendab asendamist (ingl k. substitute)
  • asfae - osa, mida soovitakse asendada
  • Kuresaare - osa, millega asendatakse
Windowsis annaks võrrelda seda käsku kui "search and replace" ehk "otsi ja asenda".

Transformeerimine

Transformeerimist kasutatakse mingi stringi üleviimiseks kindlale kujule. Näiteks kogu string väiketähtedeks, suurtähtedeks. Selleks kasutatakse sedi käsku y.

Juhin tähelepanu, et asendamisel asendatakse etteantud tingimuses tähed igal juhul - olenemata kas nad esinevad antud järjekorras või mitte!

Asendame esialgu kõik väiketähed "a" ja "v" vastavalt suurtähtedega "A" ja "V".

sed 'y/av/AV/' linnad

Väljund on üsna kole, või mis? :)

Lõpetamine

Sed ei pea ilmtingimata töötama kuni faili lõpuni. Kasutades käsku q saame määrata tingimuse, millal sed oma töö lõpetab.

Olgu meie näiteks tingimuseks "a" tähe leidumine.

sed '/a/q' linnad

Paremini sobiks näide, kus lõpetatakse sedi töö tühja rea leidmisel. Muudame kõigepealt oma faili "linnad" nii, et seal oleks pärast tartu rida üks tühi rida. Nüüd käivitame järgneva koodi.

sed '/^$/q' linnad

Nagu väljundist näeme, lõpetati programmi töö, kui tühi rida leiti. :)

Skriptide kasutamine

Sedi tööd on võimalik efektiivsemaks ja mugavamaks teha, kui kasutada skripte. Skripti sisse on võimalik kirjutada järjestik osa koode, mis käivitatakse koos sediga ja tehakse ilminemise järjekorras läbi. Nii on võimalik nt üles leida read, mis on tühjad, kustutada need ja teha kõik rea algused suurte tähtedega jne. Ja seda kõike ühe korraga. :)

Skriptifaili etteandmiseks on vaja kasutada käsku -f

Üldjoontes peaks käsk välja nägema järgnev:

sed -f skriptifail linnad

Näide 1

Kui lõime oma faili "linnad", kirjutasime sinna koleda stringi "asfae". Kasutame ära õpitud omadusi ja eemaldame selle rea, kusjuures otsides seda stringi ja kirjutame selle asemele ilusa linna nimega Haapsalu. Ja lõpetuseks salvestame uue tulemuse faili linnad_2.

sed 's/^asfae$/Haapsalu/' linnad > linnad_2

Näide 2

Teeme näite kasutades faili asendaja. Sinna sisse kirjutame järgmise koodi.

Asendaja fail hoiab endas järgmisi käske. Väiketähed "a-z", mis esinevad rea alguses asendatakse vastavate suurtähtedega "A-Z". Hiljem asendatakse string "Asfae" stringiga "Haapsalu".

# skripti eesm2rgiks on asendada k6ik v2iket2hega algavad read suurt2htedega

s/^a/A/

s/^b/B/

s/^c/C/

s/^d/D/

s/^e/E/

s/^f/F/

s/^g/G/

s/^h/H/

s/^i/I/

s/^j/J/

s/^k/K/

s/^l/L/

s/^m/M/

s/^n/N/

s/^o/O/

s/^p/P/

s/^q/Q/

s/^r/R/

s/^s/S/

s/^t/T/

s/^u/U/

s/^v/V/

s/^x/X/

s/^y/Y/

s/^z/Z/

\# asendame koleda stringi asfae stringiga Haapsalu

s/Asfae/Haapsalu/

Nüüd käivitame käsu

sed -f asendaja linnad > linnad_2

Ja tulemuseks on "linnad_2" fail, mille sisu toome siinkohal välja:

Tallinn

Tartu


Pärnu

Viljandi

Narva

Jõhvi

Valga

Võhma

Haapsalu

Kokkuvõte

Regulaaravaldised võivad teha UNIXi maailmas teie elu mitmeid kordi lihtsamaks. Kõige tähtsam on tunda õiget süntaksi ning teada, mida te teete. Kindlasti tasub tähtsate failide puhul teha varukoopiaid ja esialgu proovida test-failide peal oma kood läbi. Seda sellepärast, et ka siin toodud näited on algelised ja kindlasti mitte lõpliku teadmiste omandamiseks piisavad.

Regulaaravaldisi kasutatakse väga palju UNIXi maailmas, aga ka erinevates programmeerimiskeeltes on nad väga valjalikud ja suured abimehed.

Antud juhendis (referaadis) keskendusime UNIXi kolmele käsurea programmile - find, grep ja sed. See nimekiri pole loomulikult lõplik ja soovitan kõigil, kel vähegi huvi selle vastu on, edasi lugeda. Internet on suur ja lai. :)

Kasutatud kirjandus

http://vallaste.ee/sona.asp?Type=UserId&otsing=495

http://www.cyberciti.biz/tips/unix-linux-regular-expressions-regex-howto-tutorial.html

http://www.eenet.ee/EENet/assets/docs/abs/mall.html#regexp

http://kuutorvaja.eenet.ee/programmeerimine/regulaaravaldised.html

http://en.wikipedia.org/wiki/Regular_expression

http://kuutorvaja.eenet.ee/programmeerimine/sed/sed.html

http://www.eenet.ee/EENet/assets/docs/abs/sed.html