\newpage
\chapter{Tekstbewerkingshulpmiddelen}

\section{Vi}
Alhoewel \program{vi} wordt aangemerkt als \"e\"en van de meest
primitieve editors onder Linux, is het nog steeds een van de
meest gebruikte Unix editors.
Je zal moeten weten hoe je \program{vi} gebruikt als je
favoriete editor niet beschikbaar is.

\program{vi} heeft 2 basismodi: Opdrachtmodus en Invoegmodus.
Als eerste zullen we beginnen aan ons project te werken.
Basisfuncties in opdrachtmodus worden hieronder weergegeven. 
Degenen met een asteriks ernaast zijn opdrachten waarmee je in
de invoegmodus komt.

{\renewcommand{\baselinestretch}{.6}
\begin{table}[ht!]
\begin{center}
\begin{tabular}{|c c l|}
\hline
toets  & Voeg in  & Beschrijving\\
\thickhline
   A   & * &  Toevoegen na deze regel   \\
   a   & * &  Toevoegen na dit teken   \\
   C   & * &  Vervangen tot aan het einde van de regel    \cr
   cw  & * &  Vervang dit woord            \cr
   i   & * &  Invoegen (begin hier te typen)    \cr
   O   & * &  Begin een regel boven de cursor \cr
   o   & * &  Begin een regel onder de cursor \\
   R   & * &  Overschrijfmodus                \cr
   j   &   &  Verplaats cursor een regel naar beneden \cr
   k   &   &  Verplaats cursor een regel naar boven       \cr 
   l   &   &  Verplaats cursor een teken naar rechts    \cr
   h   &   &  Verplaats cursor een teken naar links     \cr
   x   &   &  Verwijder teken              \cr
   w   &   &  Verplaats een woord voorwaarts         \cr
   b   &   &  Ga een woord terug            \cr
   D   &   &  Verwijder tot einde regel     \cr
   dw  &   &  Verwijder dit woord           \cr
   dd  &   &  Verwijder deze regel          \cr
   d4w &   &  Verwijder 4 woorden           \cr
   yy  &   &  Kopieer een regel naar de buffer   \cr
   p   &   &  Voeg inhoud buffer in na regel \cr
   P   &   &  Voeg inhoud buffer in voor deze regel \cr
 \lt{}esc\gt&&Ga uit insert modus             \cr
\hline
\end{tabular}
\caption{\program{vi} Bewerkingen in opdrachtmodus}
\end{center}
\end{table}}


\newpage
Vanuit pneumatisch oogpunt kan het zijn dat deze opdrachten niet zo
vanzelfsprekend zijn, maar ze werden ontworpen vanwege de eenvoud en
toetsenbordefficientie.

Je kunt bestanden in opdrachtmodus lezen en schrijven door gebruik te
maken van de \program{ex}
modus die wordt aangeroepen door het intikken van een \program{:} 
(die je onderaan het \program{vi} scherm een aanwijzing zal geven)

\begin{alltt}
  :w         Schrijf dit bestand weg.
  :q         Ga uit \program{vi} zonder opslaan.
  :q!        Forceer uit \program{vi} gaan zonder opslaan.
  :w!        Forceer wegschrijven.
  :wq        Sla dit bestand op EN ga uit \program{vi}.
  :r bestand Lees ``bestand'' in op de plaats van de cursor.
\end{alltt}

Zoek-, vervang- en uitvoeropdrachten worden op vergelijkbare wijze uitgevoerd:

\begin{samepage}
\begin{alltt}
  /pattern               \comment{Zoek naar ``pattern'' en verplaats de cursor
daar naartoe}
  :1,100 s/blue/green/g  \comment{Vervang op regel 1 tot 100, blauw door groen}
  :1,\$   s/blue/green/g  \comment{Vervang op alle regels blauw door groen}
  :'a,'b s/taart/cake/g    \comment{Vervang vanaf de markering ``a'' tot aan de markering ``b'', taart door cake}
  :1,\$   !sort           \comment{\program{sorteer} alle regels}
\end{alltt}
\end{samepage}

\begin{samepage}
Zodra we eenmaal bekend zijn met \program{vi} zullen we deze modi verder
bespreken. Als eerste starten we de editor door het intikken van:

\begin{alltt}
  \bash{vi invoer.txt}
\end{alltt}

Als het goed is heb je nu een leeg scherm voor je dat er ongeveer zo uit ziet

\begin{Verbatim}[fontfamily=courier,frame=single,commandchars=\\\{\}]
\fim
~
~
~
\end{Verbatim}

\end{samepage}

% \colorbox{black}{\color{white} Zoals dit}

Typ nu \program{i} en begin met het intikken van enige betekenisvolle tekst,
zoals

\begin{Verbatim}[fontfamily=courier,frame=single,commandchars=\\\{\}]
Marie had een klein lammetje, wiens pootjes zo wit waren als sneeuw.
~<esc>
~
~
\end{Verbatim} 

\begin{samepage}
De \program{i} plaatst je in invoegmodus, en de laatste
\program{\lt{}esc\gt} plaatst je terug in opdrachtmodus. Schrijf het
nu weg en ga er uit met \command{:wq}.

\begin{Verbatim}[fontfamily=courier,frame=single,commandchars=\\\{\}]
Marie had een klein lammetje, wiens pootjes zo wit waren als sneeuw.
~
~
~
~
\rv{"invoer.txt" 1 line, 58 characters written}
\end{Verbatim}
\end{samepage}

\section{Editen met \program{Pico}}
\program{Pico} is verreweg de eenvoudigste editor in het gebruik aangezien
het gewoonijk zijn opdrachten onderaan het scherm afbeeldt.
Begin door het intikken van \program{pico invoer.txt}:


\begin{alltt}
\rv{   UW PICO(tm) 3.5                File: invoer.txt                         }
\vskip4pt{}Marie had een klein lammetje, wiens pootjes zo wit waren als sneeuw...
Start xxx Regulier
   bar baz foo them@nowhere.com Regulier
Linux Rocks TurboLinux eats apples Respect
Some say Linux Rocks

\rv{^G}Get Help \rv{^O}WriteOut \rv{^R}Read File \rv{^Y}Prev Pg \rv{^K}Cut Text \rv{^C}Cur Pos
\rv{^X}Exit     \rv{^J}Justify  \rv{^W}Where is  \rv{^V}Next Pg \rv{^U}UnCut    \rv{^T}To Spell
\rule[0cm]{6.4truein}{4pt} 
\end{alltt}

Het enige probleem dat zich voordoet met \program{pico} (en andere niet-vi
editors) is dat het zich in een noodsituatie wellicht niet op je systeem
bevindt, juist wanneer je het 't hardste nodig hebt.
Druk op {\large\tt{\verb|^X|}} om  uit \program{pico} te gaan.

\newpage
\section{Editen met \program{Emacs}}
\program{Emacs} is de krachtigste van alle gewoonlijk in het gebruik
zijnde editors onder Linux. De \term{X-Window} versie wordt volledig met
alle soorten menu-opties en panels geladen. Ondanks zijn complexiteit, kun
je er met een handjevol opdrachten mee overweg.

\heading{Emacs beeindigen en bestandsmanipulatie}
\key{{\bf schrijf} een bestand weg naar disk}{C-x C-s}
\key{sla {\bf alle} bestanden op}{C-x s}
\key{beeindig Emacs permanent}{C-x C-c}
\key{{\bf lees} een bestand in in Emacs}{C-x C-f}
\key{{\bf voeg} de inhoud van een ander bestand in in deze buffer}{C-x i}
\key{schort Emacs tijdelijk op (of verklein het onder X)}{C-z}
\key{ga naar het begin van de regel}{C-a}
\key{ga naar het einde van de regel}{C-e}
\key{verwijder teken}{C-d}
\key{verwijder tot einde van regel}{C-k}
\key{verwijder en buffer tekst}{C-w}
\key{stel een markering in}{C-space}
\key{plak inhoud uit buffer}{C-y}

\heading{Emacs foutherstel en zoeken}
\key{{\bf ongedaan} maken van een ongewilde wijziging}{C-x u}
\key{{\bf afbreken} van deels getypte of uit te voeren opdracht}{C-g}
\key{herschrijf rommelig scherm}{C-l}
\key{zoek voorwaarts}{C-s}
\key{zoek achterwaarts}{C-r}
\key{reguliere expressie zoeken}{C-M-s}
\key{achterwaarts reguliere expressie zoeken}{C-M-r}

\heading{Emacs opmaak}
\key{spring huidige {\bf regel} in (modus-afhankelijk)}{TAB}
\key{inspringen {\bf region} (modus-afhankelijk)}{C-M-\\}
\key{inspringen {\bf sexp} (modus-afhankelijk)}{C-M-q}
\key{gebied inspringen {\it arg\/} kolommen}{C-x TAB}

\heading{Emacs Help}
\key{basishulp }{C-h}
\key{scroll help window}{C-M-v}
\key{Emacs Tutorial}{C-h t}
\key{apropos: toon opdrachten die overeenkomen met een string}{C-h a}
\key{toon de functie van een toets}{C-h c}
\key{beschrijf een functie}{C-h f}

\section{Mail gebruiken}
Linux wordt met verscheidene mailafhandelingsprogramma's geleverd. 
Ik geef de voorkeur aan
\program{elm} omdat ik het goed ken en het krachtig is, alhoewel \program{pine}
erg gebruiksvriendelijk en eenvoudig in het gebruik is.
We zullen beiden bespreken.

\subsection{Elm}
Start elm op door het intikken van ``\program{elm}''. 
Als het voor de eerste keer wordt opgestart, zal het je een aantal
vragen stellen over bestanden, bevestig gewoon alles met yes.

{\normalsize
\begin{Verbatim}[fontfamily=ttfamily,frame=single,commandchars=\\\{\}]
      Mailbox is '/var/spool/mail/carinhas' with 2 messages [ELM 2.5 PL1]

     1   Jan 12 * Mail Delivery Subs (61)   Returned mail: Host unknown 
\rv{    2   Jan 12 * Mail Delivery Subs (62)   Returned mail: Host unknown}

         \pipe=pipe, !=shell, ?=help, \lt{}n\gt=set current to n, /=search pattern
  a)lias, C)opy, c)hange folder, d)elete, e)dit, f)orward, g)roup reply, m)ail,
    n)ext, o)ptions, p)rint, q)uit, r)eply, s)ave, t)ag, u)ndelete, or e(x)it

Command:q
\end{Verbatim}
}
\vskip-3pt
Eenmaal binnen \program{elm}, tik je achter de opdrachtprompt de ``m'' in, 
en volgt de aanwijzingen. \program{elm} is meer opdrachtgestuurd en op 
Unix-lijkend. Bij twijfel tik je gewoon de ``q'' in om eruit te gaan. 
Gebruik de pijltjestoetsen om omhoog en omlaag te gaan door de lijst 
met berichten.

\vspace{-4pt}
\subsection{Pine}
\program{Pine} is makkelijker te leren en gebruiken, en is compatibel met
\program{elm}, dus je kunt ze uitwisselbaar gebruiken.
Gebruik de cursorpijl naar boven, naar beneden, en \lt en \gt\ pijlen 
om te navigeren.

{\normalsize
\begin{Verbatim}[frame=single,commandchars=\\\{\}]
\rv{PINE 4.10   MAIN MENU                              Folder: INBOX  2 Messages   }

          ?     HELP               -  Get help using Pine    
          C     COMPOSE MESSAGE    -  Compose and send a message      
          I     MESSAGE INDEX      -  View messages in current folder 
         \rv{\hspace{2truept}L     FOLDER LIST        -  Select a folder to view        }
          A     ADDRESS BOOK       -  Update address book             
          S     SETUP              -  Configure Pine Options          
          Q     QUIT               -  Leave the Pine program          

\rv{?} Help\hspace{1truept}                      \rv{P} PrevCmd\hspace{10pt}                \rv{R} RelNotes
\rv{O} OTHER CMDS \rv{\gt} [ListFldrs] \rv{N} NextCmd                  \rv{K} KBLock
\end{Verbatim}
}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Reguliere Expressies}

Reguliere expressies vormen een van de pilaren van Unix duisternis in
tekstverwerking.
Reguliere expressies zijn zoekmaskers die je een onheilspellende besturing geven
over hoe testkpatronen zijn te vinden.
Hier zijn de basis patroonovereenkomstsymbolen:

{\normalsize
\begin{alltt}
.      Komt met alles overeen. ``.*'' komt met alles elk willekeurig aantal
       keren overeen. Zie *
*      Komt overeen met het laatste teken of exp 0 of meer keren. a* komt
       overeen met (), a, aa, aaa, 
+      Komt overeen met het laatste teken of exp 1 of meer keer. a+ komt
       overeen met a, aa, aaa, ..
?      Komt overeen met het laatste teken of exp 0 of 1 keer. a? komt 
       overeen met (), a
{\Large^}  Komt overeen met het begin van de regel. 
^abc   komt overeen met regels die beginnen met abc.
\$     Komt overeen met het einde van een regel.
^\$    Komt overeen met lege regels.
[]     Komt overeen met tekens binnen de haken. 
       [abc] kan overeenkomen met a, b, of c.
[^]    Het tegenovergestelde van vorige opdracht: 
       [^abc] komt met alles overeen behalve a, b, of c.
()     Tekengroepering. (abc)+ komt overeen met abc, abcabc, abcabcabc, ....   
\bs{}  Komt overeen met regex tekens, zoals \bs{+}, \bs{*}, en \bs{^}.
\{n\}  Het voorgaande item wordt exact n keer vergeleken.
\{n,\} Het voorgaande item wordt n of meer keren vergeleken.
\{,m\}  Het voorgaande item is optioneel en wordt maximaal m keer vergeleken.
\{n,m\} Het voorgaande tekens wordt minstens n keer vergeleken, niet meer
        dan m keer.
\bs{b}  Komt overeen met een woordgrens: abc\bs{b} komt overeen met 
        {\bf abc} maar niet met abcd.
\bs{B}  Komt overeen met een niet woordgrens:  abc\bs{B} komt overeen met
        {\bf abc}d maar niet met abc.
\bs{w}  Komt overeen met een woord: abc\bs{w} komt overeen met {\bf abcdef},
        maar niet met abc@.
\bs{W}  Komt overeen met een onbegrensd woord: abc\bs{W} komt overeen met
        {\bf abc(!)} maar niet met abc.
\end{alltt}
}

\subsection{GREP}
\program{grep} is een hulpmiddel om te zoeken naar patronen. 
Het zoekt naar patronen in een bestand en zal ze wanneer ze zijn gevonden op
de terminal afdrukken. Deze patronen bestaan tevens uit 
\term{reguliere expressies}.
Test \program{grep} als voorheen met het bestand \file{}.

\begin{alltt}
\command{grep}\option{ [ opties ] patroon bestand.. }
\end{alltt}

{\normalsize
\begin{alltt}
   # 1. Zoek overal in het bestand naar regels waarin ``Linux'' voorkomt.
   grep Linux invoer.txt

   # 2. Zoek naar ``Linux'' in een onbegrensd woord, zoals ``TurboLinux''
   grep ``\bs{B}Linux'' invoer.txt    # Herinner je \bs{B}?

   # 3. Zoek aan het begin en einde van een regel naar ``Linux'', reguliere
        expressies.
   grep 'Linux\$' invoer.txt       # Let op de enkele aanhalingstekens om
                                   # de shell om de tuin te leiden,
   grep ^Linux invoer.txt          # omdat de shell probeert zaken als \$
                                   # te interpreteren.

   # 4. Regels beginnend met ``Linux'', eindigend op ``Respect''.
   grep '^Linux.*Respect\$' invoer.txt  #  ``.*'' betekent elk aantal van wat dan ook.

   # 5. Zoek naar lastige patronen:
    grep '<.*>' invoer.txt       # Zoek naar regel met ``<iets>''. Html tags?
\end{alltt}
}
        
\newpage
\subsection{AWK}

\program{Awk} is een patroonscanning en verwerkingstaal. De
syntax ervan luidt:

\begin{alltt}
\command{awk}\option{ 'programma' invoer-bestanden}
\end{alltt}

Wanneer het een lang programma is, is het gewoonlijk handiger dit in een bestand
te plaatsen en het als volgt als een opdracht uit te voeren:

\begin{alltt}
\command{awk}\option{ -f programmabestand invoerbestanden}
\end{alltt}

Neem nu een kijkje in de handleiding (man page). Hier zijn een aantal
\"e\"enregelige voorbeelden:

{\normalsize
\begin{Verbatim}[fontfamily=courier,commandchars=\\\{\}]
\command{awk '/xxx/' invoer.txt}  # Zoek naar ``xxx'' in \term{invoer.txt} 
    Vrijwel alle reguliere expressies werken binnen de //.
\command{awk 'NF > 0' invoer.txt} 
    Dit programma drukt elke regel af dat uit tenminste 1 veld bestaat. Het
is een makkelijke manier om lege regels uit een bestand te verwijderen.
\command{awk -F: '\{ print \$1 \}' /etc/passwd | sort }
    Dit programma drukt een gesorteerde lijst van de loginnamen van alle
gebruikers af.
\command{awk 'END \{ print NR \}' invoer.txt }
    Dit programma telt het aantal regels in invoer.txt
\command{awk 'NR % 2 == 0' invoer.txt} 
    Dit programma drukt de even genummerde regels van invoer.txt af.
    Als je de expressie `NR % 2 == 1' zou hebben gebruikt, zouden er oneven
genummerde regels zijn afgedrukt.
\command{awk '\{if (length(\$0) > max) max=length(\$0)\} END \{print max\}' invoer.txt}
    Dit programma drukt de lengte van de langste invoerregel af.
\command{awk 'length(\$0) > 80' invoer.txt} # Druk de regels af die uit meer dan
80 tekens bestaan.
Aangezien de enkele regel een relationele expressie als patroon heeft en
geen actie, worddt de standaardactie, het afdrukken van het record gebruikt.
\command{awk 'BEGIN \{ for (i = 1; i <= 7; i++) print int(101 * rand()) \}'} 
    Dit programma drukt zeven willekeurige nummers af van 0 tot en met 100.
\command{ls -lg *.txt | awk '\{ x += \$5 \} ; END \{print "total bytes:" x \}'}
    Dit programma drukt het totaal aantal bytes af door door alle .txt 
    bestanden in beslag wordt genomen.
\end{Verbatim}
}

\newpage
\subsection{Perl}
\program{Perl}, ``Practical Extraction and Report Language'' is de Swiss Army
Knife van alle scripttalen. Het heeft alles behalve een Megawatt laser, en 
een gootsteen.
Perl bevat een zeer complete set \term{reguliere expressies} en een grote
set Unix systeemaanroepen:

\begin{alltt}
\command{perl}\option{ [opties] [ programma ] }
\end{alltt}

Op de opdrachtregel kun je gebruik maken van de syntax
\begin{alltt}
\command{perl}\option{ -ne 'opdracht' bestand }
\end{alltt}

waarbij dit de opties zijn

\begin{alltt}
\dkey{-e 'command'}{voer een \term{opdracht} uit in plaats van een scriptbestand}
\dkey{-n}{voer het script uit op elke regel invoer \term{file}}
\dkey{-w}{Druk waarschuwingen af voor je script \term{file}}
\end{alltt}


Ook als is het nog zo complex, we kunnen een paar \"e\"enregelige
\program{perl} opdrachten leren waarmee wonderen kunnen worden verricht:

\begin{alltt}
   # 1. Zoek in \term{invoer.txt} naar regels beginnend met ``Linux Rocks''
   perl -ne 'if ( /^Linux Rocks/ ) \{print\} ' invoer.txt

   # 2. Zoek ``Linux'' in een onbegrensd woord, zoals ``TurboLinux''
   perl -ne 'if ( /\bs{B}Linux/ ) \{print\} ' invoer.txt

   # 3. Zoek naar ``Linux Rocks'' en vervang het door ``Rocks Linux''.
   #    Reguliere expressies matching ()'s get named \$1, \$2, \$3, etc..
   perl -ne 's/^(Linux) (Rocks)/\$2 \$1/; { print} ' invoer.txt

   # 4. Regels beginnend met ``Linux'', eindigend op ``Rocks''.
   perl -ne 'print if /^Linux Rocks\$/ ' invoer.txt

   # 5. Zoek naar e-mailadressen in \term{invoer.txt}:
   perl -ne 'print if (/(\bs{w}[.\bs{w}]*\bs{@}\bs{w}[\bs{w}\.-]+\bs{w})/gm)' invoer.txt
        
\end{alltt}

\newpage
\subsection{SED}
\program{sed} is een stream editor, wat betekent dat het als een
transportband op je terminal werkt. De tekstbestanden passeren je
terwijl het zijn werk doet. 

\begin{alltt}
\command{sed}\optie{ [script ] bestand.. }
\end{alltt}

\program{sed} is aardig complex dus we zullen hier slechts wat simpele
gebruiken en voorbeelden laten zien...

\begin{alltt}
   # 1. Print van regel 1 tot en met 32 het regelnummer
   sed '1,32 \{= ; \}' invoer.txt   # Werkt vrijwel bijna als in \program{VI}

   # 2. Verwijder de regels 1 tot en met 32
   sed "1,32 d" invoer.txt        # \emph{:1,32 d} in \program{VI}

   # 3. Onder UNIX: converteer DOS newlines (CR/LF) naar Unix formaat
   sed 's/^M\$//' invoer.txt      # Onder bash ^M = C-v C-m, tcsh ^M = C-v C-j
        
   # 4. Onder DOS: converteer Unix newlines (LF) naar DOS formaat
   sed 's/\$//' invoer.txt        # methode 1
   sed -n p invoer.txt            # methode 2

   # 5. Verwijder van elke regel de witruimte (spaties/tabs) waarmee de regel
	begint.
   #    '^t' stelt een echt tab-teken voor. ^t => Ctrl-V Ctrl-I.
   sed 's/^[ ^t]*//' invoer.txt   # OK in \program{VI} zonder enkele 
                                  # aanhalingstekens.

   # 6. Verwijder van elke regel witruimte (spaties/tabs) aan het einde vd regel
   sed 's/[ ^t]*\$//' invoer.txt  # zie hierboven de opmerking over '^t'

   # 7. Verwijder op elke regel ZOWEL de voorafgaande als eindigende witruimte
   sed 's/^[ ^t]*//;s/[ ^t]*\$//' invoer.txt   # zie hierboven de opmerking over
'^t'

   # 8. Vervang "foo" door "bar"
   sed 's/foo/bar/' invoer.txt        # vervang 1e instance foo door bar.
   sed 's/foo/bar/4' invoer.txt       # vervang alleen 4e instance in een regel
   sed 's/foo/bar/g' invoer.txt       # vervang ALLe instances binnen een regel
   sed '/baz/s/foo/bar/g' invoer.txt  # Sub ALLEEN bij regels waarin "baz" voorkomt.
   
   # 9. Overeenkomst van regel waarin ``Regulier'' voorkomt:
   sed '/^Regulier/d' invoer.txt       # Verwijder regels beginnend met ``Regulier''
   sed '/Regulier\$/d' invoer.txt      # Verwijder regels eindigend op ``Regulier''

   #10. Vanaf ``Start'' tot ``Linux'', vervang appels door sinaasappels.
   sed  /Start/,/Linux/{s/appels/sinaasappels/} invoer.txt

\end{alltt}
