Sed

Allikas: Kuutõrvaja

Sed

Sed on voo editor (ingl. k. stream editor), mis on tuletatud klassikalisest UNIXi rea editorist Ed. Sed laseb endast andmeid läbi ja muutes neid Sedi käskudega määratud viisil. Praktiliselt saab Sedi kasutada ka kahendfailide jaoks.

Sedi kasutamine eeldab regulaaravaldiste koostamise oskust, kusjuures Sed toetab mittelaiendatud metasümbolite hulka.

Tööruum

Sed redigeerib rida haaval tema sisendisse suunatud teksti. Rida on kahe järjestikuse reavahetuse märgi (\n) vahele jääv tekst.

Sed.jpg

Niisiis, Sed asub tegelema sisendisse saabunud esimese reatäie tekstiga. See paigutatakse mälubufrisse, mida nimetatakse tööruumiks. Tööruumis olevale rakendatakse järgemööda kõiki Sedi käske. Tulemus saadetakse väljundisse. Kõik kordub järgmiste sisendist tööruumi võetud andmetega kuni sisendandmete lõppemiseni.

Sedi käivitamine

Sedi käivitamisel tuleb suunata andmed tema sisendisse, näidata, millised Sedi käske rakendada ja kuhu väljund suunata.

Kuvame näiteks tekstifaili linnad esimesed 10 rida

bash~$ sed '10q' linnad

Sama, kasutades sisendi ja väljundi ümbersuunamisi

bash~$ cat linnad | sed '10q' > 10.esimest.linna 

Sedi käsud tuleb kirjutada käsurealt antuna apostroofide vahele; kui neid on mitu, siis peab iga ette kirjutama '-e'

bash~$ cat linnad | sed -e '10q' -e '5q'

Kui kasutada mitmeid käske on otstarbekam tekitada skript

#!/bin/sed -f
10q
5q

mis käivitatakse selliselt

bash~$ cat linnud | skript.sed

Kui sisendiks on fail, siis Sed ei riku originaali ära. Kindlasti salvestada tulemus teise nimega faili.

Adresseerimine

Adresseerimise mõte on näidata, millistele ridadele käske rakendada. Kui te ei näita aadressi, siis rakendatakse käske igale reale.

Sedi käskude süntaks selline:

[aadress[,aadress]]käsk[argumendid]

Aadressi võib esitada:

   * pöördudes rea poole rea numbriga
   * valides välja read regulaaravaldisega 

Aadressile järgnev hüüumärk (!) inverteerib aadressiga näidatud ridade valiku.

Reanumbritega adresseerimine

Soovides kustutada viiendat rida:

5d

Soovides kustutada kõik read peale viienda

5!d

Soovides kustutada teisest kuni kahekümnenda reani. Kui ridu nii palju pole, kustutatakse nii palju kui saab.

2,20d

Soovides kustutada viimast rida

$d

Regulaaravaldistega adresseerimine

Ühe regulaaravaldisega adresseerimisel rakendub käsk kõigile ridadele, mis regulaaravaldisega klapivad. Kustutame näiteks tühjad read

/^$/d

Kahe regulaaravaldisega adresseerides toimivad käsud ridadele, alustades sellest, kus esimene regulaaravaldis klappis ja lõpetades sellega, kus teine regulaaravaldis klappis. Selliseid vahemikke, kus toime avaldub, võib olla mitu. Toome näiteks välja kõik HTMLi tabelid

/<TABLE/,/<\/TABLE/!d

Siin on näha, et regulaaravaldiste jaoks erilise tähendusega sümboleid, nagu kaldkriip, tuleb kaikaga põgeda.

Kustutamine

Adresseerimise punktis selgitati paratamatult ka kustutamist, mis toimub käsuga d (ingl. k. delete).

Asendamine

Asendamine toimub käsuga s (ingl. k. substitute) järgmise skeemi kohaselt:

[aadress[,aadress]]s/muster/asendaja/võti

Asendame igal real kõik sõnad 'loomaed' ja 'Loomaed' sõnaga 'Loomaaed':

s/[Ll]oomaed/Loomaaed/g

Võti 'g' näitab, et real tuleb teha kõik asendused; soovides igal real teha vaid ühe asenduse, esimesel jätke võti g ära.

Kustutada ip aadressi viimane element, -r lülitab sisse extended regular expression funktsionaalsuse ([ [ : digit : ] ] järgnevuses pole tühikuid, wiki sünktaksi vältimiseks)

$ echo "10.0.10.15" | sed -r 's/\.[ [ : digit : ] ]+$//'
10.0.10

Asendavad erisümbolid

  • & - asendaja, mille väärtuseks on string, millega muster klappis; nt. kirjutame kõik aastaarvud sulgudesse
      s/[0-9][0-9][0-9][0-9]/(&)/
  • \n, kus n on arv - asendaja, mille väärtuseks on string millega mustris n-inda \( ja \) vahele paigutatu klappis. Näiteks vahetame failis, kus on kaks ühe või enama tühikuga eraldatud tulpa, need tulbad ära
     s/\(.*\) \(.*\)/\2 \1/

Transformeerimine

Transformeerimine toimub käsuga y, mille tulemusena asendatakse sümbolid vastavalt nende positsioonile toodud järjekorras. Sarnaselt UNIXi programmile tr

[aadress]y/abcdefgh/ABCDEFGH/

Tulemusena asendatakse 'a' 'A' -ga, 'b' 'B' -ga jne. vaatamata sellele, kas 'a'-le järgneb 'b'.

Lõpetamine

Sedile on võimalik käsuga q (ingl. k. quit) öelda, et ta teatud tingimusel lihtsalt lõpetaks. Näiteks kohates esimest tühja rida.

/^$/q

Sedi Skriptid

Alguses viitasime võimalusele Sedi käske võtta failist. See on otstarbekas, kui soovitakse rakendada tööruumile mitut käsku järgemööda.

Toome näite ühest ühtlustajast, mis asendab kõik tekstis leiduvad sõnad halb, paha, hirmus sõnaga jube.

bash~$ cat yhtlustaja
# vaike sedi skript, mis teeb halva jubedaks
s/halb/paha/g
s/paha/hirmus/g
s/hirmus/jube/g

Ning tema käivitamine toimub selliselt:

bash~$ sed -f yhtlustaja tekstifail

Toodud näite juures tuleb panna tähele, et iga käsk muudab tööruumi ja järgnev käsk toimib muudetud tööruumile.

Kommentaarideks mõeldud read algavad # märgiga.

Sedis pole võimalik programmeerimisele iseloomulike konstruktsioonide, nagu tingimuste ja tsüklite, täiendav tarvitamine. Nt ei ole võimalik Sedile 'öelda', et asenda esimese rea sõna Tartu Tallinnaga, kui viimases reas pole 'A' tähte. See pole võimalik, kuna Sed ei tea ette, mis tuleb; aga kui ta juba teab, siis on esimese rea jaoks lootusetult hilja. See pole aga Sedi puudus, vaid hoopis tugevus. Kuivõrd ta ei hoia korraga kõiki andmeid mälus, siis võimaldab ta tegeleda ka väga suurte failidega.

Failist lugemine ja salvestamine

Käsuga r (ingl. k. read) saab täita tööruumi failist võetava sisuga ning selle seejärel saata väljundisse. Näiteks kohates sisendi lõppu, saadetakse väljundisse faili lopp sisu.

$r lopp

Sarnaselt saab käsuga w (ingl. k. write) kirjutada teatud tingimustel tööruumi sisu faili. Näiteks kirjutame kõik read, mis sisaldavad sõna 'Priit' ühte faili priidu.read ja teise faili mardi.read vastavalt sõna 'Mart' sisaldavad read:

/Priit/w priidu.read
/Mart/w mardi.read

Lisamine

Lisamine on sarnane eelpool käsitletud asendamisele selle erinevusega, et lisatakse või vahetatakse välja terve rida. Lisada saab kolme moodi:

  • c - vahetamine (ingl. k. change)
  • i - ette lisamine (ingl. k. insert)
  • a - järgi lisamine (ingl. k. append)

Eripäraks on see, et lisada ei saa käsurealt, vaid ainult skripti failist:

bash~$ cat lisa_aadress
/Priit Paju/a\
Ploomi 6\ 
Tartu linn\
Eestimaa

Eeldatavasti on failis priidu.kutse sobivas kohas järgnevus 'Priit Paju', misjärgi kirjutatakse järgmisele reale aadress. Oluline on, et märk \ oleks viimane sümbol real.

bash~$ sed -f lisa_aadress priidu.kutse

Sed'iga käsureal faili jooksvalt muutmine

Selleks tuleb anda käsk

sed -i -e 'sedi käsud' failinimi

Näiteks asendame failis kõik sõnad esimene, teisega

sed -i -e 's/esimene/teine/g'

Muutame vaid teatud ridu

Asendame failis sõna esimene tekstiga teine igal real kus sisaldub sõna kolmas

sed '/kolmas/s/esimene/teine/g'

Näited

Vahel programmid logivad mitmerealisi sissekandeid, nt PostgreSQL kirjutab sissekande esimese rea alates esimesest positsioonist ja järgnevad read algavad tabulaatoriga; sellise logifaili teisendamiseks nö üherealiseks sobib öelda

$ sed ':a;N;$!ba;s/\n\t/ /g' < tekst

Markused

  • Tavaliselt kasutatakse eraldajana / märki, kusjuures sed kasutab eraldajana s järel näidatud märki, nt
$ echo "see asendatakse ara" | sed s/asendatakse/asendati/
see asendati ara
$ echo "see asendatakse ara" | sed s_asendatakse_asendati_
see asendati ara

Praktiliselt on sellest kasu kui avaldises endas sisaldub palju / märke, mida tuleks / eraldaja kasutamisel \ abil varjestada.