Mustand: sisu ei ole veel tehniliselt ega keeleliselt täielikult kontrollitud ega toimetatud.

Peatüki vaade

Linux/Unix/macOS käsurea kiirõpik

Praegu loed peatükki Vood ja tabelid: sort, uniq, wc, pr, join, mis kuulub osasse Osa IV: Tekst, otsing ja automatiseerimine.

Vood ja tabelid: sort, uniq, wc, pr, join

Selles peatükis vaatame, kuidas ridu loendada, sortida, rühmitada ja tabelilaadseks vormida.

Loogika

Kui sul on palju ridu, aitab see peatükk neist kokkuvõtte teha. Tüüpiline töövoog on: sorteeri, koonda, loenda.

Kiirspikker

  • sort sorteerib ridu
  • uniq eemaldab järjestikused duplikaadid
  • uniq -c loendab järjestikuseid duplikaate
  • wc -l loendab ridu
  • wc -w loendab sõnu
  • join ühendab kahest failist ühise väljaga read
  • pr vormib väljundi printimiseks või veergudesse

Käivita need käsud


printf 'pirn\noun\npirn\nploom\n' > viljad.txt
sort viljad.txt
sort viljad.txt | uniq
sort viljad.txt | uniq -c

echo 'üks kaks kolm neli' | wc -w
printf 'a\nb\nc\n' | wc -l

printf '1 Mari\n2 Jaan\n' > nimed.txt
printf '1 Tartu\n2 Tallinn\n' > linnad.txt
join nimed.txt linnad.txt
pr -2 viljad.txt

Sõnade lugemine ja tõstu muutmine


echo 'Tere tere maailm' | tr '[:upper:]' '[:lower:]' | tr ' ' '\n' | sort | uniq -c

See on klassikaline Unix-laadne voog: teisenda, jaga ridadeks, sorteeri, loenda.

join eeldab tavaliselt, et mõlemad sisendfailid on ühise välja järgi sorditud. pr on kasulik siis, kui tahad väljundit kiirelt veergudesse või printimiseks vormida.

Päris näide: kõige sagedamad sõnad

Kui tahad näha, miks sort | uniq -c | sort -nr on nii klassikaline, siis kasuta näidisandmefaili:


cp data/sample-words.txt sonad.txt
sort sonad.txt | uniq -c | sort -nr | head -n 15

Selle töövoo loogika on:

  • sort toob samad sõnad järjestikku
  • uniq -c loendab järjestikused kordused
  • sort -nr paneb suurimad loendused ette

Just see on üks Unix-laadse tekstitöötluse põhivõtteid.

Päris näide: logitasemete kokkuvõte

Fail data/app.log sobib hästi väikese logianalüüsi jaoks.


cut -d ' ' -f 2 data/app.log | sort | uniq -c | sort -nr

Siin:

  • cut -d ' ' -f 2 võtab välja logitaseme
  • sort | uniq -c loendab tasemed kokku
  • tulemuseks saad näiteks INFO, WARN, ERROR sagedused

See on hea näide, sest siin kohtuvad tekstifilter, väljavõte ja koondamine.

Päris näide: palju ridu ja palju sõnu

Kui tahad kiiresti aru saada, kui suur üks tekstifail on:


wc -l data/sample-text.txt
wc -w data/sample-text.txt

See annab kaks eri mõõdet:

  • mitu rida
  • mitu sõna

Mõlemad on praktilised, aga nad ei tähenda sama asja.

Päris näide: join

join tundub alguses natuke kuiv, aga ta on väga hea väikeste tabelite ühendamiseks.


printf '1 Tallinn\n2 Tartu\n3 Narva\n' > linnad.txt
printf '1 Harjumaa\n2 Tartumaa\n3 Ida-Virumaa\n' > maakonnad.txt
join linnad.txt maakonnad.txt

Siin:

  • mõlemal failil on esimene väli ühine võti
  • join ühendab sama võtmega read kokku

Oluline detail:

  • sisendfailid peavad tavaliselt võtme järgi sorditud olema

Päris näide: pr

Kui tahad kiirelt sõnaloendit veergudesse panna:


head -n 20 data/sample-words.txt | pr -4 -t

Siin:

  • -4 teeb neli veergu
  • -t jätab päise ja jaluse ära

See ei ole tänapäeval kõige sagedasem tööriist, aga väga õpetlik lühikese käsurea vormindusvõttena.

Veel üks väga praktiline näide on nummerdatud loendi panemine mitmesse veergu:


seq -w 0 99 | pr -5 -t

Siin:

  • seq -w 0 99 teeb loendi 00 kuni 99
  • pr -5 -t jagab selle viide veergu

Kui tahad suurema hulga numbreid panna ühele pr loogilisele lehele, siis saab mängida lehepikkusega:


seq -w 0 9999 | pr -8 -t -l 1250

Selle loogika on:

  • seq -w 0 9999 teeb numbrid 0000 kuni 9999
  • -8 teeb kaheksa veergu
  • -t eemaldab päise ja jaluse
  • -l 1250 ütleb, et ühe pr lehe kõrgus on 1250 rida

Oluline täpsustus:

  • see tähendab “üks pr leht”
  • see ei tähenda automaatselt “üks päris A4 paberileht”

Päris printimisel sõltub tulemus veel fontidest, paberi suurusest ja sellest, kas prindid terminalist, PDF-ist või mõnest muust keskkonnast.

Kui tahad lihtsalt rahulikult mitut veergu eelvaadata, siis väiksem näide on tavaliselt parem:


seq -w 0 199 | pr -8 -t | less

Locale ja sortimine

sort ei tööta alati kõigis keskkondades täpselt ühtemoodi, sest tulemus sõltub ka locale'ist.

See on eriti nähtav täpitähtede puhul.

Näide:


printf 'Õun\nÄmber\nÖö\nUdu\n' > tahed.txt
sort tahed.txt
LC_ALL=C sort tahed.txt

Siin võib juhtuda, et:

  • tavaline sort kasutab sinu keskkonna locale'it
  • LC_ALL=C sort ... sorteerib lihtsama baitide loogika järgi

See tähendab, et sort tulemus ei ole alati "absoluutne tõde", vaid sõltub keskkonnast.

Kui töötled eestikeelset teksti, siis tasub seda meeles pidada.

Minitest

  1. Loenda faili read.
  2. Sorteeri sõnaloend tähestiku järgi.
  3. Loenda, mitu korda iga sõna esineb.
  4. Proovi join abil ühendada kaks väikest faili ühise esimese välja järgi.
  5. Tee data/app.log failist logitasemete sagedustabel.