\documentclass[finnish,a4]{seminar}

\include{slide-preamble}

\begin{document}

\slidepagestyle{sectslide}
\centerslidesfalse

\slidesection{Tekstinprosessointiohjelmat}

\begin{slide}

\slideheading{Tekstinprosessointiohjelmien yleinen toimintatapa (1)}

\bi
\item Useimmat tekstinprosessointiohjelmat (\cmdln{cat}, \cmdln{grep},
\ldots) toimivat kahdella erilaisella tavalla.
\item Jos niille annetaan tiedostojen nimiä argumenteiksi, ne lukevat
syötteensä kyseisistä tiedostoista, esim. \cmdln{grep misu juttu.txt}.
\item Sen sijaan jos niille ei kerrota yhtäkään tiedostonimeä, ne
lukevat syötteensä \newterm{vakiosyötteestä} (standard input).
Komentotulkki määrää, mistä vakiosyöte varsinaisesti tulee.
\item Oletuksena vakiosyöte tulee suoraan käyttäjältä.  Tästä syystä
esimerkiksi komento \cmdln{grep foo} hakee foo"-sanoja käyttäjän
kirjoituksesta.  Syötteen loppumisesta voi ilmoittaa painamalla
\cmdln{C-d}.
\ei

\end{slide}

\begin{slide}

\slideheading{Virroista (1)}

\bi
\item Vakiosyöte on yksi esimerkki \newterm{vakiovirroista}.  Virrat
ovat ikään kuin kanavia, joita pitkin kulkee tekstiä.  Muita
vakiovirtoja ovat \newterm{vakiotuloste} ja \newterm{vakiovirhe}.
\item Vakiovirtojen idea on siinä, että ohjelma voi sokkona lukea
syötettä, tuottaa tulostetta ja kirjoittaa virheilmoituksia tietämättä,
mistä syöte oikeasti tulee tai mihin tuloste / virheilmoitukset oikeasti
menevät.
\item Oletuksena vakiosyöte tulee yksinkertaisesti käyttäjältä ja
vakiotuloste ja "-virhe menevät käyttäjän näytölle luettaviksi.
Esimerkiksi \cmdln{cat -n} (ilman muita argumentteja) lukee käyttäjältä
syötettä linja kerrallaan ja näyttää linjat numeroituina.

\newslide

\item Komentotulkin ohjaustoiminnoilla esim.~syötteen voi yhtä hyvin
antaa ohjelmalle tiedostosta tai vaikkapa toisen ohjelman tulosteesta.
Meillä on jo käsiteltykin tulosteen ohjaus tiedostoon (\cmdln{>}"- ja
\cmdln{>{}>}"-rakenteet).
\item Tämä mahdollisuus ohjailla ohjelmien syötettä, tulostetta ja
virheilmoituksia on tärkein ohjelmien yhdistelytapa Unixissa.  Erityisen
tärkeä on rakenne, jolla annetaan yhden ohjelman tuloste toisen
syötteeksi.  Tämän rakenteen nimi on putki ja sitä merkitään merkillä
\cmdln{|}.
\item Kaikki seuraavien kalvojen ohjelmat osaavat lukea myös
vakiosyötettä, jos niille ei anneta yhtään tiedostoa argumentiksi.
\ei

\end{slide}

\begin{slide}

\slideheading{\cmdln{cat}, \cmdln{wc} --- uudestaan}

\commandscheme{cat}{ [ -n ] [ -s ] \textit{tied1} \textit{tied2}
...}{CATenate}
Yhdistää peräkkäin argumentteina olevat tiedostot.  Valitsimella
\cmdln{-n} (Numerate) numeroi rivit.  Valitsimella \cmdln{-s} (Squeeze)
korvaa peräkkäiset tyhjät rivit yhdellä.

\commandscheme{wc}{ [ -l ] [ -w ] [ -c ] [ -L ] \textit{tied1}
\textit{tied2} ...}{Word Count}
Laskee rivit, sanat ja merkit argumenttitiedostoista ja näyttää
tuloksen.  Valitsimilla \cmdln{-l} (Lines), \cmdln{-w} (Words) ja
\cmdln{-c} (Characters) kertoo \emph{vain} linjojen, sanojen tai
merkkien määrän (vastaavasti).  Valitsimella \cmdln{-L} (Line) kertoo
pisimmän rivin pituuden.

\end{slide}

\begin{slide}

\slideheading{\cmdln{grep} --- uudestaan}

\commandscheme{grep}{ [ -C \textit{n} ] [ -v ] [ -x ] [ -i ] [ -o ]
\textit{sana} \textit{tied1} \textit{tied2} ...}{Global RegExp Print}
Etsii sanaa argumenttitiedostoista.  Oletuksena tulostaa linjat, joilla
kyseinen sana löytyy.  Valitsimella \cmdln{-C} (Context) tulostaa myös
löydöslinjojen ympäriltä pari linjaa.  Valitsimella \cmdln{-v} (?)
tulostaa kaikki linjat, joista sanaa \emph{ei} löydy.  Valitsimella
\cmdln{-x} (eXact) tulostaa vain ne linjat, joilla on haettu sana eikä
mitään muuta.  Valitsimella \cmdln{-i} (Insensitive) ei kiinnitä
huomiota suurten ja pienten kirjainten eroon.  Valitsimella \cmdln{-o}
(Only) tulostaa vain sen kohdan, joka täsmäsi (ei koko linjaa).

\commandscheme{grep}{ -r \textit{sana} \textit{hakemisto}}{Global RegExp
Print / Recursive}
Etsii sanaa \newterm{rekursiivisesti} kaikista hakemiston sisältämistä
tiedostoista.

\end{slide}

\begin{slide}

\slideheading{Uusia tekstinprosessointikomentoja}

\commandscheme{head}{ [ -\textit{n} ] \textit{tied1} \textit{tied2}
...}{HEAD of file}
\commandscheme{tail}{ [ -\textit{n} ] \textit{tied1} \textit{tied2}
...}{TAIL of file}
Näyttää \textit{n} ensimmäistä (\cmdln{head}) tai viimeistä
(\cmdln{tail}) riviä tiedostoista.  Oletus 10 riviä.

\commandscheme{sort}{ [ -n ] [ -r ] [ -k \textit{n} ] \textit{tied1}
\textit{tied2} ...}{SORT}
Järjestää argumenttitiedostojen rivit (oletuksena aakkosjärjestykseen).
Valitsin \cmdln{-n} (Numeric) tuottaa numeerisen järjestyksen; valitsin
\cmdln{-r} (Reverse) kääntää järjestyksen päinvastaiseksi; valitsimella
\cmdln{-k} (Key) voi valita, monennenko sanan mukaan järjestetään.

\newslide

\commandscheme{uniq}{ [ -c ] [ -d ] \textit{tied}}{UNIQue lines}
Näyttää argumenttitiedoston siten, että peräkkäiset samat linjat on
poistettu.  Valitsimella \cmdln{-c} (Count) kertoo lisäksi, kuinka monta
kertaa mikin linja oli syötteessä.  Valitsimella \cmdln{-d} (Duplicates)
kertoo \emph{vain} ne linjat, joita oli useampi kappale.

\commandscheme{cut}{ [ -d \textit{merkki} ] -f \textit{n} \textit{tied1}
\textit{tied2} ...}{CUT fields}
Näyttää argumenttitiedostot siten, että jokaisesta linjasta näytetään
vain \textit{n}:s kenttä (Field).  Kenttäerottimena käytetään
\textit{merkki}:a (Delimiter), joka on oletuksena sarkain
(tabulaattori).

\commandscheme{diff}{ [ -u ] \textit{tied1} \textit{tied2}}{DIFFerence}
Näyttää erot \textit{tied1}"- ja \textit{tied2}"-tiedostojen välillä.

\end{slide}

\begin{slide}

\slideheading{\cmdln{tr} --- kielitieteilijän perustyökalu}

Tämä on yksinkertaisuudessaan hämmentävän monipuolinen ohjelma.
\cmdln{tr} osaa lukea syötettä vain vakiosyötteestä, sille ei voi antaa
argumentiksi tiedostonimiä.

\commandscheme{tr}{ \textit{mistä} \textit{mihin}}{TRanslitterate}
Muuntaa syötteen \textit{mistä}"-merkit vastaaviksi
\textit{mihin}"-merkeiksi.  Esimerkiksi \cmdln{tr ab uo} muuttaa kaikki
a:t u:ksi ja b:t o:ksi.  Merkkijoukoissa voi olla myös väliviivalla
merkittyjä merkkivälejä, esim. \cmdln{tr A-M a-m} muuntaa kaikki isot
kirjaimet A:n ja M:n väliltä pieniksi.

\commandscheme{tr}{ -d [ -c ] \textit{merkkejä}}{TRanslitterate / Delete}
Poistaa syötteestä annetut merkit.  Valitsimella \cmdln{-c} (Complement)
poistaa kaikki merkit paitsi annetut merkit.  Myös tämä ymmärtää
merkkivälejä.

\newslide

\commandscheme{tr}{ -s \textit{merkkejä}}{TRanslitterate / Squeeze}
Jos syötteestä löytyy useampia peräkkäisiä kappaleita jotain merkkiä,
joka kuuluu annettuun merkkijoukkoon, ne korvataan yhdellä.

\cmdln{tr}:n vipusia voi myös yhdistää.  Esimerkiksi \cmdln{tr -sc
A-Za-z ?} korvaa kaikki yhden tai useamman merkin ei"-kirjainjaksot
kysymysmerkillä.

Tärkeimpiä \cmdln{tr}:n käytöistä lienee sanojen paneminen omille
riveilleen.  Se onnistuu komennolla
\begin{verbatim}
tr " " \\012
\end{verbatim}
joka siis muuttaa välilyönnit rivinvaihdoiksi.  Tähän hipsujen käyttöön
tutustutaan tuonnempana.

\end{slide}

\begin{slide}

\slideheading{Tositoimiin: prosessointikomennot}

\bi
\item Ota jokin isohko tiedosto raakamateriaaliksesi.  Jos sinulla ei
ole sellaista, voit esim.~hakea jonkin \www"-sivun komennolla
\cmdln{wget}, jos se löytyy järjestelmästä, tai kirjoittaa
\cmdln{emacs}"-ohjelmalla jonkin tekstin.
\item Etsi tiedostosta erilaisia sanoja sisältäviä linjoja
\cmdln{grep}"-komennolla.  Esim. \cmdln{grep -i and tiedosto.txt}.
Kokeile \cmdln{grep}"-komennon eri valitsimien vaikutusta
lopputulokseen.
\item Kokeile erilaisia merkkivaihdoksia ja "-poistoja
\cmdln{tr}"-komennolla.  Esim. \cmdln{tr uio üíå <tiedosto.txt}.
\item Katso, mitä tiedostossa \cmdln{/etc/passwd} on.  Vertaa komennon
\cmdln{cut -d: -f1 /etc/passwd} tulokseen.  Kokeile hakea muitakin
kenttiä.

\newslide

\item Näytä \cmdln{/etc/passwd} käyttäjätunnusten mukaan aakkostettuna
komennolla \cmdln{sort /etc/passwd} ja nimien mukaan aakkostettuna
komennolla \cmdln{sort -t: -k5 /etc/passwd}.
\item Kokeile \cmdln{sort}"-komennon eri valitsimien vaikutusta
lopputulokseen.
\item Anna komento \cmdln{grep 'a.*i'} ja kirjoittele erilaisia sanoja
kokeillaksesi, mihin \cmdln{grep} tarttuu.
\item Anna pelkkä komento \cmdln{cat -n} ja kirjoittele kaikenlaista
katsoaksesi, mitä se tekee.
\item Tee \cmdln{cut}"-komennon eri valitsimilla raakamateriaalistasi
erilaisia listittyjä versioita.
\ei

\end{slide}

\slidesection{Vakiovirrat}

\begin{slide}

\slideheading{Tekstinprosessointiohjelmien yleinen toimintatapa (2)}

\bi
\item Erityisesti tekstinprosessointiohjelmat, mutta usein Unixin
muutkin ohjelmat, on suunniteltu toimimaan tarvittaessa
\newterm{filttereinä}: ne ottavat vakiosyötteestä jotain, tekevät sille
jonkin muunnoksen ja antavat tuloksen vakiotulosteeseen.
\item Filttereistä pystyy rakentelemaan yhdistelemällä hyvinkin
monimutkaisia kokonaisuuksia.
\item Useimmat tekstinprosessointiohjelmat suostuvat lukemaan syötettä
sekä joistain tiedostoista että vakiosyötteestä.  Tällöin vakiosyötettä
merkitään tiedostonimellä \cmdln{-}.  Esimerkiksi komento \cmdln{diff
makkara -} vertailee eroja \cmdln{makkara}n ja vakiosyötteen välillä.
\ei

\end{slide}

\begin{slide}

\slideheading{Virroista (2)}

\bi
\item Vakiosyötteen ja "-tulosteen pointti on siis se, että ne sallivat
ohjelman toimia filtterinä, muunnoksena tiedolle, josta ei tiedetä,
mistä se tulee, eikä mihin se menee.
\item Vakiovirheen pointti on siinä, etteivät virheilmoitukset
sotkeutuisi muuhun tulosteeseen, vaan ne voivat tulla suoraan käyttäjän
nähtäviksi tai ohjata esim. tiedostoon tarkasteltaviksi.
\item Vakiovirheen voi ohjata tiedostoon rakenteella \cmdln{2>
tiedosto}, joka liitetään komennon perään samoin kuin \cmdln{>}"-ohjaus.
Vakiosyötteen voi ohjata tiedostosta rakenteella \cmdln{< tiedosto}.
\ei

\end{slide}

\begin{slide}

\slideheading{Putket}

\bi
\item Putkilla filtterikomennoista voi rakennella pitkiä
``tuotantolinjoja'', joissa jokainen komento tekee oman hommansa ja
lähettää tuloksensa taas eteenpäin seuraavalle komennolle.
\item Putkia komentojen välille muodostetaan kirjoittamalla kaksi
komentoa erotettuna putkimerkillä (\cmdln{|}).
\item Esim.~\cmdln{grep jukkeli foo.txt | cat -n} etsii
\cmdln{foo.txt}"-tiedostosta jukkeli"-sanaa ja lähettää tuloksen
\cmdln{cat}:lle numeroitavaksi.
\item Putkimerkkiä kohden komentotulkki tekee siis kolme asiaa: perustaa
putken, ohjaa edellisen käskyn tulosteen putkeen, ja ohjaa seuraavan
käskyn syötteen putkesta.
\ei

\end{slide}

\slidesection{Putkien käyttö}

\begin{slide}

\slideheading{Putkikomentojen lukeminen}

\notebox{Esimerkki: \\
\cmdln{cat -n a.html | grep href | head -30 | tail -1}}
Tämä komento näyttää \cmdln{a.html}"-tiedoston 30. linkin sekä
rivin numeron, jolla kyseinen linkki sijaitsee.  Mutta miten se toimii?

\bi
\item \cmdln{cat -n} lisää rivinumerot linjojen eteen.
\item \cmdln{grep href} etsii rivit, joilla esiintyy sana href, ts.
rivit joilla on linkkejä.  (Jos rivillä on useampi kuin kaksi linkkiä,
ohjelmamme ei toimi oikein.  Linkit pitää oikeasti rivittää
\cmdln{tr}:lla ensin.)
\item \cmdln{head -30} jättää tästä jäljelle vain 30 ensimmäistä riviä.
\item \cmdln{tail -1} poimii näistä vain viimeisen rivin,
ts.~\cmdln{grep}:n tulosteen 30.~rivin.
\ei

\newslide

Putkikomentojen ymmärtämisessä on usein hyödyllistä nähdä, millaista
tekstiä kulkee minkäkin kahden komennon välillä.  Tämä onnistuu siten,
että kirjoittaa putkilinjan komento kerrallaan ja katsoa aina, millaista
tulostetta syntyy missäkin vaiheessa.

Sen sijaan halutun putkilinjan muodostaminen onkin vaikeampi homma: se
edellyttää avointa ajattelua, erilaisten ratkaisumahdollisuuksien
etsimistä.  Yksi hyväksi havaittu tapa tehdä tätä on lisäillä
putkilinjaan yksi komento kerrallaan sen mukaan, mikä ``näyttää'' vievän
meitä lähemmäs ratkaisua.  Tämä tietysti edellyttää intuitiota...

Joitain nyrkkisääntöjä on: kun halutaan valita tiettyjä linjoja
(\newterm{selektio}), \cmdln{grep} on yleensä oikea vastaus; kun
halutaan valita linjoista tietty osa (\newterm{projektio}), \cmdln{cut}
on yleensä oikea vastaus; ja kun halutaan muuttaa tiedon rakennetta,
\cmdln{tr} on yleensä oikea vastaus.

\end{slide}

\begin{slide}

\slideheading{Tyypillisiä linjan loppuun liitettäviä komentoja}

On monia komentoja, jotka on selkeästi suunniteltu putkilinjan
lopettimiksi.  Näistä ylivoimaisesti yleisin on \cmdln{less}.
\bi
\item Lisää komennon loppuun \cmdln{| less} jos haluat selailla tulosta
edestakaisin.
\item \cmdln{| lpr}, \cmdln{| mpage} tai \cmdln{| a2ps} on kätevä tapa
tulostaa lopputulos.
\item \cmdln{| mail tyyppi@jossain} lähettää tuloksen
sähköpostiviestinä.
\item \cmdln{| head} on näppärä tapa katsoa vain vähän, minkänäköistä
tulosta putkilinja tuottaa.
\ei

\end{slide}

\begin{slide}

\slideheading{Välihuomatutus: lainaaminen}

\bi
\item Kuten huomattu, komentolinjat koostuvat jonosta sanoja.
\item Joskus kuitenkin ``sanan'' pitää sisältää välilyöntejä, jos
esimerkiksi nimeää tiedoston, jonka nimessä on välilyönti.  Samoin
erilaiset maagiset merkit, kuten \cmdln{<}, \cmdln{>}, \cmdln{|} ja
\cmdln{*}, halutaan joskus antaa komennolle sellaisinaan argumentiksi.
\item Sekalaisesta merkkipötköstä voi tehdä yhden ``sanan'' panemalla
sen \newterm{hipsuihin} (\cmdln{"} tai \cmdln{'}).
\item Esimerkiksi merkkijonoa \cmdln{hui sentään} voi etsiä komennolla
\cmdln{grep 'hui sentään' tiedosto}.
\ei

\end{slide}

\begin{slide}

\slideheading{Putkiesimerkkejä (1)}

\notebox{\cmdln{ls | wc -l}}
Laskee, kuinka monta tiedostoa on oletushakemistossa.  (Kun \cmdln{ls}
tulostaa muualle kuin näytölle, se tulostaa yhden tiedoston per rivi.)

\notebox{\cmdln{history | grep '|' | less}}
Antaa selailla, mitä putkikomentoja on antanut.

\notebox{\cmdln{cut -d: -f5 /etc/passwd | sort}}
Luettelee koneen käyttäjät aakkosjärjestyksessä.

\notebox{\cmdln{echo testausta | mail -s koe hj@iki.fi}}
Lähettää \cmdln{hj@iki.fi}:lle viestin otsikolla ``koe'' joka sisältää
vain sanan ``testausta''.

\end{slide}

\begin{slide}

\slideheading{Putkiesimerkkejä (2)}

\begin{verbatim}
tr -s " " \\012 <aine.txt | sort | uniq | fmt | less
\end{verbatim}
Näyttää aakkosellisen listan tiedoston aine.txt sanoista.

\bi
\item \cmdln{tr} muuntaa välilyönnit rivinvaihdoiksi ja korvaa samalla
useammat peräkkäiset rivinvaihdot yhdellä (jottei tule tyhjiä rivejä).
\item \cmdln{sort} järjestää sanat aakkosjärjestykseen ja siirtää ne
samalla peräkkäin \cmdln{uniq}:a varten.
\item \cmdln{uniq} jättää vain eroavat sanat jäljelle eli sanan toistot
poistetaan.
\item \cmdln{fmt} uudelleenrivittää syötteen enintään 74"-merkkisiksi
riveiksi.
\item \cmdln{less} sallii tarkastella tulosta mukavasti.
\ei

\end{slide}

\begin{slide}

\slideheading{Putkiesimerkkejä (3)}

\begin{verbatim}
history | grep " cd " | sort -k 3 | mpage -8 -Plp
\end{verbatim}
Tulostaa käytetyt \cmdln{cd}"-käskyt järjestettynä sen mukaan, mihin
tiedostoon niillä on menty, 8 sivua yhdellä paperilla.

\bi
\item \cmdln{history} antaa käytetyt käskyt.
\item \cmdln{grep} valitsee niistä vain ne, joissa on sana \cmdln{cd}.
\item \cmdln{sort} järjestelee ne kolmannen sanan mukaan (1.~sana on
historianumero, toinen cd"-komento).
\item \cmdln{mpage} tekee niistä postscriptia (tiedostomuoto, jota
tulostimet ymmärtävät) ja lähettää sen tulostimelle \cmdln{lp}.
\ei

\end{slide}

\begin{slide}

\slideheading{Tositoimiin: putket}

\bi
\item Näissäkin tarvitset jonkin raakamateriaalitiedoston...
\item Rivitä tiedoston sanat \cmdln{tr}"-komennolla:
\begin{verbatim}
tr " " \\012 <tiedosto.txt
\end{verbatim}
\item Lisää tämän perään erilaisia putkeksi erilaisia
\cmdln{tr}"-komentoja, joilla saat poistetuksi sanoista suurien ja
pienten kirjainten erot, välimerkit, ja niin edelleen.
\item Kokeile myös tutkia sanojen vokaalirakennetta suodattamalla niistä
konsonantit pois: \ldots \cmdln{| tr -dc aeiouyåäö}
\item Lisää tähän vielä perään \ldots \cmdln{| sort | uniq -c} katsoaksesi,
mitkä ovat yleisiä vokaalirakenteita.
\item Kokeile putkiesimerkeissä esitettyjä komentoja siten, että lisäät
putkilinjaan elementin kerrallaan ja katselet tulosta joka välissä.
\ei

\end{slide}

\end{document}

