Beetaversioon: sisu on enamasti terviklik ja avalikuks katsetamiseks valmis, kuid vajab veel tehnilist, keelelist ja kasutatavuse kontrolli.

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 neid kokku võtta. 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 käsku uniq sortimata sisendiga ja oodatakse kõigi duplikaatide kadumist
  • aetakse segi ridade loendamine ja sõnade loendamine
  • unustatakse, et join eeldab tavaliselt sobivalt ette valmistatud sisendit

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 loendamine ja tähesuuruse 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.

Näide: kõige sagedasemad 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 võib alguses tunduda abstraktne, kuid sobib hästi 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 käsu pr leht“
  • see ei tähenda automaatselt üht füüsilist A4-paberilehte

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

Lokaat ja sortimine

sort ei tööta alati kõigis keskkondades täpselt ühtemoodi, sest tulemus sõltub ka keele- ja piirkonnasätetest (locale).

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 keele- ja piirkonnasätteid
  • 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.

wc -l loendab täpselt reavahetusi, mitte visuaalseid ridu. Kui faili viimane tekstirida ei lõpe reavahetusega, jääb see selle loenduse alt välja. uniq võrdleb alati kõrvutisi ridu; kogu faili korduste koondamiseks tuleb samad read eelnevalt kõrvuti tuua, tavaliselt sort-iga.

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