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

Loogika

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

Kiirülevaade

Eesmärk on muuta suur hulk ridu kokkuvõtteks: sortida, loendada, rühmitada ja vajadusel tabelina siduda.

KäskMilleksMida tavaliselt näed
sortsea read järjekordasamad read uues järjekorras
uniqkoonda kõrvuti duplikaadidkorduvad read kaovad või saavad loenduri
wcloenda ridu, sõnu või märkelühike arvuline kokkuvõte
joinühenda kaks faili ühise välja järgiseotud read ühises väljundis
prvormi veergudesse või printimisekslehekülje- või veerupaigutus

Tüüpilised algaja vead

  • kasutatakse uniq-i sortimata sisendi peal ja oodatakse kogu duplikaatide kadumist
  • aetakse segi ridade loendamine ja sõnade loendamine
  • unustatakse, et join eeldab tavaliselt sobivalt ette valmistatud sisendit

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

pr ei ole tänapäeval kõige sagedasem tööriist, kuid sobib kiireks veergudesse vormindamiseks.

Näiteks saab nummerdatud loendi panna 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.

Peatüki täisspikker

Töövood

Eesmärk

tüüpiline töövoog on: sorteeri read, koonda kordused ja loe tulemused kokku

Põhikujud

  • sort viljad.txtsordi read
  • sort viljad.txt | uniqeemalda kordused
  • sort viljad.txt | uniq -cloe kordused
  • wc -l data/sample-text.txtloe read
  • wc -w data/sample-text.txtloe sõnad
  • join nimed.txt linnad.txtühenda võtme järgi
  • prjaga veergudeks

Olulisemad lipud, märgid ja kiirnupud

  • sort -nnumbrid
  • sort -rtagurpidi
  • uniq -cloenda kordused
  • wc -lridade arv
  • wc -wsõnade arv
  • pr -2kaks veergu