1. Failioperatsioonid ja filtreerimine

Enamasti tegeldakse käsureal failidega. Käesolevas osas tutvustame, kuidas jälgida ja filtreerida faili sisu, kuidas hankida failist vajalik info üheainsa käsuga ja kuidas vähesega vaevaga sortida faili sisu.

1.1. cat, tail, head, tee: faili näitamise käsud

Neil käskudel on peaaegu täiesti ühesugune süntaks: käsu_nimi [võtmed] [failid] ja neid võib kasutada torus. Kõigi nendega saab lasta näidata faili mingit osa vastavalt teatud kriteeriumidele.

cat ühendab ehk konkateneerib failid ja näitab tulemusi standardväljundis, milleks on tavaliselt Teie arvuti ekraan. See on üks levinumaid käske. See võib välja näha näiteks selline:

# cat /var/log/mail/info

mis näitab e-posti deemoni logifaili sisu standardväljundis[23]. Käsul cat on üks väga kasulik võti (-n), millega saab näha ka reanumbreid.

Mõned failid, näiteks töötavate deemonite logifailid, võivad tihtipeale olla väga suured [24] ja nende täielik näitamine ekraanil sestap üsna mõttetu. Tavaliselt pakubki Teile ju huvi vaid mingi osa neist, teatud read. Selleks saab kasutada käsku tail. Nii näitab järgmine käsk vaikimisi faili /var/log/mail/info 10 viimast rida:

# tail /var/log/mail/info

Selliseid failid nagu logid muutuvad tavaliselt dünaamiliselt, sest antud logiga seotud deemon lisab logifaili pidevalt uusi toiminguid ja sündmusi. Kui soovite muudatusi interaktiivselt vaadata, kasutage võtit -f:

# tail -f /var/log/mail/info

Antud juhul näidatakse kõiki failis /var/log/mail/info toimuvaid muudatusi otsekohe ekraanil. Käsu tail kasutamine võtmega -f on üsna kasulik, kui soovite teada, kuidas Teie süsteem töötab. Nii saate näiteks logifaili /var/log/messages jälgides olla kursis süsteemi ja mitmesuguste deemonite teadetega.

Kui kasutate käsku tail enam kui ühe faili jaoks, näidatakse enne sisu omaette real faili nime. Ka selle korral saab kasutada võtit -f ning sellest on suur abi nägemaks, kuidas süsteemi erinevad osad omavahel suhtlevad.

Võtmega -n saab lasta näidata faili viimast n rida. Näiteks kahe viimase rea näitamiseks tuleb anda käsk sellisel kujul:

# tail -n2 /var/log/mail/info

Nagu käskude puhul ikka, saab korraga kasutada ka mitut võtit. Nii näiteks võite anda võtmed -n2 ja -f, mis tähendab, et Teile näidatakse faili kaht viimast rida ja sealjuures uuendatakse neid vastavalt sellele, kuidas lisandub ridu jälgitavasse faili.

Käsk head on äärmiselt sarnane käsuga tail, ainult et sellega saab lasta näidata faili esimesi ridu. Järgmine käsk näitab vaikimisi faili /var/log/mail/info esimest 10 rida:

# head /var/log/mail/info

Nagu käsu tail puhul, saab ka siin võtmega -n määrata näidatavate ridade arvu. Näiteks kahe esimese rea näitamiseks andke käsk sellisel kujul:

# head -n2 /var/log/mail/info

Käske võib ka koos kasutada. Kui soovite näiteks lasta näidata ainult rida 9 ja 10, võite koostada käsu, milles head valib kõigepealt faili esimesed 10 rida ning edastab need siis toru kaudu käsule tail.

# head /var/log/mail/info | tail -n2

Viimane osa valib kaks viimast rida ja näitab neid ekraanil. Samalaadse koondkäsuga saab näidata näiteks 20. rida alates faili lõpust:

# tail -n20 /var/log/mail/info |head -n1

Selles näites anname käsule tail korralduse valida faili 20 viimast rida ja saata need toru kaudu käsule head. Käsk head näitab seejärel ekraanil saadud andmete esimest rida.

Oletame, et soovite näha ekraanil just viimati toodud näite rida ja selle siis failina tulemused.txt salvestada. Siin tuleb appi utiliit tee. See süntaks on järgmine:

tee [võtmed] [fail]

Nüüd võime modifitseerida varasemat käsku:

# tail -n20 /var/log/mail/info |head -n1|tee tulemused.txt

Toome veel ühe näite. Soovime valida 20 viimast rida ja salvestada need faili tulemused.txt, aga lasta ekraanil näidata 20 valitud reast ainult esimest. Selleks tuleb käsk anda järgmisel kujul:

# tail -n20 /var/log/mail/info |tee tulemused.txt |head -n1

Käsuga tee saab tarvitada väga kasulikku võtit -a, mis lubab lisada andmed juba olemasoleva faili lõppu.

Järgmises osas vaatame, kuidas kasutada käsku grep filtrina Postfixi teadete eraldamisel muudelt teenustelt pärit teadetest.

1.2. grep: sõnede leidmine failides

Ei käsu nimi ega lahtiseletus (“General Regular Expression Parser” ehk üldine regulaaravaldiste parsija) pole just paljuütlevad, kuid käsk ise on õigupoolest väga lihtne ja väga võimas: grep otsib Teie antud mustrit ühes või rohkemas failis. Süntaks on järgmine:

grep [võtmed] <muster> [üks või rohkem faili]

Kui anda mitu faili, siis tulemust näidates lisatakse alatu iga sobiva rea ette ka failinimi. Võtmega -h saab failinime näitamise keelata, võtmega -l aga lasta näidata ainult failinimesid. Muster kujutab endast regulaaravaldist, kuigi see võib olla ja enamasti ongi lihtsalt sõna või sõnaosa. Levinumad võtmed on järgmised:

  • -i: tõstutundetu otsing (s.t. ei arvestata väike- ja suurtähe erinevust).

  • -v: vastupidine otsing. Näidatakse ridu, mis ei vasta mustrile.

  • -n: näidatakse iga leitud rea numbrit.

  • -w: grep'ile antakse korraldus leida ainult mustriga sobivad terviksõnad.

Võtame nüüd uuesti ette e-posti deemoni logifaili. Oletame, et soovite leida failis /var/log/mail/info kõik read, millel leidub muster postfix. Selleks tuleb anda käsk:

# grep postfix /var/log/mail/info

Kui soovite leida kõik read, kus EI LEIDU mustrit postfix, tuleb kasutada võtit -v:

# grep -v postfix /var/log/mail/info

Torus saab kasutada käsku grep.

Oletame, et soovite leida kõik teated e-kirjade eduka saatmise kohta. Sel juhul tuleb filtreerida kõik read, mille lisas logifailile e-posti deemon (sisaldab mustrit postfix), kusjuures need peavad sisaldama teadet eduka saatmise kohta (status=sent)[25]:

# grep postfix /var/log/mail/info |grep status=sent

Antud juhul kasutatakse käsku grep kaks korda. See on küll lubatud, aga mitte just väga elegantne... Sama tulemuse võib saada utiliidiga fgrep. fgrep on õigupoolest seesama, mis käsk grep -F. Kõigepealt tuleb luua fail, milles leiduksid ühekaupa ridadele kirjutatud mustrid. Selle faili saab luua nii (me anname siinkohal failile nimeks musrid.txt):

# echo -e 'status=sent\npostfix' >./mustrid.txt

Kontrollige tulemust käsuga cat. \n on spetsiaalne muster tähendusega “new line” (ehk 'uus rida').

Seejärel kutsuge välja järgmine käsk, mis kasutab grep'i “topeltväljakutsumise” asemel faili mustrid.txt ja utiliiti fgrep:

# fgrep -f ./mustrid.txt /var/log/mail/info

Failis ./mustrid.txt võib olla nii palju mustreid kui vaja. Näiteks selleks, et valida kirjad, mis saadeti edukalt aadressile peter@mandriva.com, tuleb see lihtsalt lisada faili ./mustrid.txt järgmise käsuga:

# echo 'peter@mandriva.com' >>./mustrid.txt

Mõistagi om võimalik grep kombineerida käskudega tail ja head. Kui soovite näiteks leida teated eelviimase aadressile peter@mandriva.com saadetud kirja kohta, tuleb anda käsk:

# fgrep -f ./mustrid.txt /var/log/mail/info | tail -n2 | head -n1

Siin rakendatakse filter, nagu eespool kirjeldatud, ja edastatakse tulemus torusse käskudele tail ja head. Need üheskoos valivadki andmetest välja eelviimase väärtuse.

1.3. Regulaaravaldised ja filtreerimine egrep'iga

Käsu grep korral oleme seotud mustrite ja fikseeritud andmetega. Kuidas aga leida näiteks kõik e-irjad, mida on saadetud igale firma “ABC” töötajale? Kõigi nende aadresside ületähendamine pole sugugi lihtne, sest väga kergesti võib mõni puudu jääda või siis tuleb lausa logifaili käsitsi kaevuda.

Nagu fgrep'i korral, pakub grep välja omaette versiooni ka käsule grep -E: egrep. See kasutab mustrite asemel regulaaravaldisi, mis muudavad teksti “greppimise” palju tundlikumaks.

Lisaks metamärkide kasutamisele (neist rääkis lähemalt Sektsioon 3, “Metamärkide kasutamine shellis”) saab kasutada veel mõningaid regulaaravaldis:

  • [:alnum:] (kõik tähed ja kõik numrbrid), [:alpha:] (kõik suur- ja väiketähed) ja [:digit:] (kõik numbrid) on kasutatavad märgiklasside vahetu määratlemise asemel. Sellel on veel üks pluss: see arvestab ka muid kui inglise tähestiku tähti, samuti süsteemi lokaati.

  • [:print:] tähistab kõiki märke, mida saab näidata ekraanil.

  • [:lower:] ja [:upper:] tähistavad vastavalt kõiki väike- ja suurtähti.

Klasse on rohkemgi, nendega aitab Teil tutvuda manuaalikirje egrep(1). Siintoodud on lihtsalt kõige levinumad.

Regulaaravaldisele võib järgneda mõni kordusoperaator:

?

Eelnev element ei ole kohustuslik ja peab esinema mitte enam kui üks kord.

*

Eelnev element peab esinema null või enam korda.

+

Eelnev element peab esinema üks või enam korda.

{n}

Eelnev element peab esinema täpselt n korda.

{n,}

Eelnev element peab esinema n või rohkem korda.

{n,m}

Eelnev element peab esinema vähemalt n, aga mitte rohkem kui m korda.

Kui panna regulaaravaldis sulgudesse, saab seda hiljem uuesti kasutada. Oletame, et määrasite avaldiseks [:alpha:]+. See võib tähistada näiteks sõna. Kui soovite tuvastada kaks korda esinevad sõnad, võite panna selle sulgudesse ja kasutada uuesti kordajaga \1, kui tegemist on esimese grupiga. Te saate ära kasutada kuni 9 sellist “mälu”.

$ echo -e "abc def\nabc abc def\nabc1 abc1\nabcdef\nabcdabcd\nabcdef abcef" > testfile
$ egrep "([[:alpha:]]+) \1" testfile
abc abc def
$
[Märkus]Märkus

Märgid [ ja ] kuuluvad grupinimesse, mistõttu need tuleb kaasata antud märgiklassi. Esimene [ annab teada, et me kasutame märgigruppi, teine on osa grupinimest ning seejärel tulevad mõlemale vastavad sulgevad märgid ].

Ainuke tagastatud rida ongi selline, mis ainsana vastas kahele tühikuga eraldatud tähegrupile. Ükski teine grupp regulaaravaldisega ei sobinud.

Kasutada võib ka märki | kas vasakul pool | või sellest paremal pool asuva avaldise sobivuse leidmiseks. See operaator ühendab need avaldised. Püüame eespool loodud faili testfail kasutades leida avaldised, mis sisaldavad ainult topeltsõnu või topeltsõnu numbritega:

$ egrep "([[:alpha:]]+) \1|([[:alpha:][:digit:]]+) \2" testfail
abc abc def
abc1 abc1
$

Pange tähele, et teise sulgusid kasutava grupu puhul oli vajalik kasutada \2, sest muidu poleks leitud meile vajalikke sobivusi. Õigupoolest oleks antud juhul tõhusam regulaaravaldis selline:

$ egrep "([[:alnum:]]+) \1" testfail
abc abc def
abc1 abc1
$

Lõpuks tuleb arvestada, et teatud märkide leidmiseks tuleb need “varjestada” ehk nende ette längkriips lisada. Neiks märkideks on: ?, +, {, |, (, ) ning mõistagi ka \. Nende leidmiseks tuleb kirjutada: \?, \+, \{, \|, \(, \) ja \\.

See lihtne nõks aitab Teil vältida korduvate sõnade kirjutamist “Teie Teie” tekstis.

Kõik tööriistad järgivad regulaaravaldiste kasutamisel toodud või nendega väga sarnaseid reegleid. Kui Te kulutate veidi aega nende omandamisele, aitab see Teid tunduvalt paljude tööriistade, näiteks sed'i juures. sed võimaldab Teil teksti töödelda ja muu hulgas seda muuta ka regulaaravaldisi kasutades.

1.4. wc: faili elementide loendamine

Käsku wc (Word Count ehk 'sõnade arv') kasutatakse faili ridade, sõnede ja sõnade arvu leidmiseks. Sellest on abi ka pikima rea pikkuse leidmisel. Süntaks on järgmine:

wc [võtmed] [failid]

Kasutada saab järgmisi võtmeid:

  • -l: ridade arvu näitamine.

  • -w: sõnade arvu näitamine.

  • -m: märkide koguarvu näitamine.

  • -c: baitide arvu näitamine.

  • -L: teksti pikima rea pikkuse näitamine.

Vaikimisi näitab wc ridade, sõnade ja märkide arvu. Toome mõned näited:

Kui me soovime teada saada süsteemi kasutajate arvu, on käsk selline:

$ wc -l /etc/passwd 

Kui me soovime teada saada süsteemi CPU-de arvu, on käsk selline:

$ grep "model name" /proc/cpuinfo |wc -l

Eelmises osas hankisime teadete nimekirja edukalt failis ./mustrid.txt loetletud aadressidele saadetud e-kirjade kohta. Kui soovime teada, mitu teadet see sisaldab, võib filtri tulemuse toru kaudu suunata käsule wc:

# fgrep -f ./mustrid.txt /var/log/mail/info | wc -l

1.5. sort: faili sisu sortimine

Võimsa sortimisutiliidi süntaks on järgmine[26]:

sort [võtmed] [failid]

Vaatleme faili /etc/passwd sortimist. Nagu näete, pole see sorditud:

$ cat /etc/passwd

Kui me soovime selle sortida kasutajanime välja (login) alusel, tuleb anda käsk:

$ sort /etc/passwd

Käsk sort sordib andmed vaikimisi kasvavas järjestuses esimese välja alusel (meie näites on selleks kasutajanimi ehk login). Kui soovime sortida andmed kahanevas järjestuses, tuleb kasutada võtit -r:

$ sort -r /etc/passwd

Kõigil kasutajatel on oma UID, mis on pandud kirja faili /etc/passwd. Järgmise käsuga saab sortida faili kasvavas järjestuses välja UID järgi:

$ sort /etc/passwd -t":" -k3 -n

Me kasutasime järgmisi käsu sort võtmeid:

  • .t":"; annab käsule sort teada, et väljaeraldajaks on sümbol ":".

  • -k3: sortimine tuleb sooritada kolmanda veeru järgi.

  • -n: annab teada, et sortimine tuleb ette võtta arvandmetega, mitte tähestiku järgi.

Sama käsu võib anda ka teistpidi järjestuses:

$ sort /etc/passwd -t":" -k3 -n -r

Pange tähele, et käsul sort on veel kaks tähtsat võtit:

  • -u: range järjestus - topeltväljad jäetakse näitamata.

  • -f: tõstu eiramine (väiketähti peetakse võrdseks suurtähtedega).

Kui me tahame leida suurima UID-ga kasutajat, tuleb anda käsk:

$ sort /etc/passwd -t":" -k3 -n |tail -n1

millega me sordime faili /etc/passwd kasvavas järjestuses veeru UID järgi ning suuname tulemusel toru kaudu käsule tail. See näitab sorditud nimekirja esimest väärtust.



[23] Mõnes käesolevas osas toodud näites kasutatakse reaalseid töö- ja serverilogide faile (teenused, deemonid jne.). Kontrollige nende järgimisel, et syslogd (see võimaldab logida deemoni tegevust) ja vastav deemon (meie näiteks Postfix) töötavad ja et te tegutsete administraatorina (root). Te võite muidugi alati ka toodud näiteid rakendada muude failide peal.

[24] Fail /var/log/mail/info sisaldab infot kõigi saadetud kirjade kohta, teateid POP-protokolli kasutavate kasutajate kirjade tõmbamise kohta jne.

[25] Kuigi on võimalik ka filtreerida lihtsalt staatuse mustri järgi, proovige ka meie näidet, sest me soovime siin näidata uut käsku.

[26] Me tutvustame käsku sort siin ainult lühidalt, kuigi selle kohta võiks kirjutada terve paksu raamatu.