next_inactive up previous


Programare shell: filtre de text, sed, awk

Razvan Deaconescu

20 noiembrie 2005

Filtre de text

Scripturile shell sunt folosite deseori pentru prelucrarea output-ului unei comenzi . Aceasta sarcina este deseori destul de simpla: afisarea unei parti a output-ului prin filtrarea catorva linii. Alteori, insa, este necesara o procesare mult mai sofisticata.

Comenzi folosite ca si filtre de text sunt head, tail, grep, sort, uniq, tr.

head, tail

Cele doua comenzi sunt folosite pentru afisarea numai a primelor sau a ultimelor linii de text din cadrul unui fisier. Sintaxa lor este asemanatoare:

head [-n lines] files
tail [-n lines] files

Primul argument, daca exista, afiseaza primele, respectiv ultimele n linii din text. Lipsa acestuia impune n = 10.

Exemple de comenzi sunt:

razvan@ragnarok:~/cfiles/solab/labs$ ls -l
total 44
drwxr-xr-x  2 razvan razvan 4096 Nov 16 00:01 lab1
drwxr-xr-x  3 razvan razvan 4096 Oct 12 00:02 lab2
-rwxr-xr-x  1 razvan razvan  937 Oct 19 00:53 lab2html.sh
drwxr-xr-x  3 razvan razvan 4096 Oct 19 00:50 lab3
drwxr-xr-x  3 razvan razvan 4096 Oct 26 01:09 lab4
drwxr-xr-x  3 razvan razvan 4096 Nov  2 09:47 lab5
drwxr-xr-x  3 razvan razvan 4096 Nov 12 19:56 lab6
drwxr-xr-x  2 razvan razvan 4096 Nov 16 12:43 lab7
drwxr-xr-x  2 razvan razvan 4096 Nov 20 12:34 lab8
drwxr-xr-x  5 razvan razvan 4096 Oct 17 19:52 solab
drwxr-xr-x  2 razvan razvan 4096 Nov 12 20:06 tema1
razvan@ragnarok:~/cfiles/solab/labs$ ls -l | head -3
total 44
drwxr-xr-x  2 razvan razvan 4096 Nov 16 00:01 lab1
drwxr-xr-x  3 razvan razvan 4096 Oct 12 00:02 lab2
razvan@ragnarok:~/cfiles/solab/labs$ ls -l | tail -4
drwxr-xr-x  2 razvan razvan 4096 Nov 16 12:43 lab7
drwxr-xr-x  2 razvan razvan 4096 Nov 20 12:34 lab8
drwxr-xr-x  5 razvan razvan 4096 Oct 17 19:52 solab
drwxr-xr-x  2 razvan razvan 4096 Nov 12 20:06 tema1
razvan@ragnarok:~/cfiles/solab/labs$

In cazul comenzi tail o optiune utila este -f care mentine fisierul de vizualizat deschis pe masura ce programele scriu in el, spre exemplu pentru a vizualiza un fisier de log pe masura ce informatiile sunt scrise in el:

$ tail -f /var/log/apache/access_log

grep

Comanda grep permite localizarea liniilor intr-un fisier care contine o expresie cautata. Sintaxa de baza este

$ grep word file

file este numele fisierului in care vrem sa gasim cuvantul word. Un exemplu de utilizare este:

razvan@ragnarok:~/cfiles/solab/labs$ grep latex lab2html.sh
latex2html -split 0 -nosubdir -show_section_numbers "$BASE.tex" 2>&1 > /dev/nulllatex2html -split 0 -nosubdir -show_section_numbers "$BASE-teme.tex" 2>&1 > /dev/null
latex2html "$BASE.tex" 2>&1 > /dev/null
latex "$BASE.tex" 2>&1 > /dev/null

De multe ori dorim sa realizam cautarea in mod case-insensitive (adica sa nu conteze faptul ca se cauta UNIX sau unix). Pentru aceasta folosim optiunea -i.

Cand nu se precizeaza un fisier se foloseste intrarea standard, grep devenind ideal pentru lucrul cu pipes. De exemplu:

razvan@ragnarok:~/cfiles/solab/labs/lab8$ last | head -100 | grep tty
root     tty1                          Wed Nov 16 11:00 - down   (00:00)
razvan   tty1                          Wed Nov 16 00:07 - 00:08  (00:01)

O alta optiune utila este -v. Aceasta permite cautarea acelor linii care NU contin cuvantul transmis ca parametru. Spre exemplu, daca dorim afisarea utilizatorilor care nu au ca si director de baza un director de forma /home/nume, vom folosi comanda:

razvan@ragnarok:~/cfiles/solab/labs/lab8$ grep -v /home /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
lp:x:7:7:lp:/var/spool/lpd:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
.......

Un alt exemplu de folosire este parsarea output-ului comenzii ps:

razvan@ragnarok:~/cfiles/solab/labs/lab8$ ps -af | grep lyx
razvan    3767  3719  0 12:19 pts/0    00:00:05 lyx
razvan    4219  3719  0 12:53 pts/0    00:00:00 grep lyx
razvan@ragnarok:~/cfiles/solab/labs/lab8$ ps -af | grep lyx | grep -v grep
razvan    3767  3719  0 12:19 pts/0    00:00:05 lyx

Optiunea -n permite afisarea numarului liniei care continea cuvantul cautat.

Putem de asemenea sa afisam numai fisierele care contin acel cuvant (fara afisarea liniilor). Pentru aceasta folosim optiunea -l (listare). De obicei este folosita in conjunctie cu optiunea -r pentru cautarea recursiva in cadrul unei structuri de directoare:

razvan@ragnarok:~/cfiles/solab/labs$ grep -r -l "#include <sys/wait.h>" .
./lab2/lab2.lyx
./lab2/lab2.tex
./lab2/wait_zombie.c
./lab2/simple_exec.c
./solab/lab2/lab2.lyx
./solab/lab2/lab2.tex
./solab/lab2/wait_zombie.c
./solab/lab2/simple_exec.c
./lab6/lab6.lyx
./lab6/mmap.c
./lab6/lab6.tex

tr

Comanda tr (transliterate) este folosita pentru a translata caracterele dintr-un set de caractere intr-un alt set de caractere. Sintaxa de baza este:

tr 'set1' 'set2'

Spre exemplu, daca am dori sa aflam numarul de cuvinte dintr-un text, am translata toate caracterele speciale in spatii cu o comanda de forma:

$ tr '!?":'\[\]{}(),.' ' ' < file

Caracterele [ si ] au fost escapate folosind \. Daca dorim sa translatam literele mari in litere mici, folosim:

$ tr 'A-Z' 'a-z' < file

In cazul in care setul set2 are mai putine caractere decat setul set1 acestea vor fi multiplicate pentru a ajunge la aceeasi dimensiune.

Urmatorul pas ar fi eliminarea spatiilor redundante. Optiunea -s (squeeze) inlocuieste o succesiune de doua sau mai multe caractere cu unul singur. Un exemplu este:

razvan@ragnarok:~/cfiles/solab/labs$ echo shell programming | tr -s 'lm'
shel programing

sort

Comanda sort este utilizata pentru sortarea liniilor alfabetic. Un exemplu de utilizare este:

razvan@ragnarok:~/cfiles/solab/labs$ echo -en "alfa\nomega\ngamma\nbeta\n"
alfa
omega
gamma
beta
razvan@ragnarok:~/cfiles/solab/labs$ echo -en "alfa\nomega\ngamma\nbeta\n" | sort
alfa
beta
gamma
omega

O optiune utila in cazul sort este sortarea dupa valoarea numerica a sirurilor. Pentru aceasta folosim -n. De exemplu:

razvan@ragnarok:~/cfiles/solab/labs$ echo -en "10\n43\n4\n9\n123\n5\n" | sort 10
123
4
43
5
9
razvan@ragnarok:~/cfiles/solab/labs$ echo -en "10\n43\n4\n9\n123\n5\n" | sort -n
4
5
9
10
43
123

De multe ori output-ul apare intr-o forma in care elementele de sortat sunt intr-o alta coloana (nu prima, cea folosita implicit de sort). Pentru aceasta se poate folosi optiunea -k (key). Sintaxa, in cazul folosirii acestei optiuni, este:

sort -k start, end file

Aici start este coloana de start a cheii, iar end este coloana de stop a cheii. Prima coloana este cea dupa care se face sortarea, iar, in cazul in care sunt doua sau mai multe elemente egale, se face deosebirea intre acestea folosind coloana urmatoare din cheie, etc.

Exemplu de utilizare este:

sort -rn -k 2,2 file     ; sorteaza dupa a doua coloana

uniq

Se pot elimina duplicatele folosind optiunea -u la sort. Totusi, de multe ori este util sa afisam de cate ori apare un cuvant. Pentru aceasta vom folosi comanda uniq cu optiunea -c. Atentie! uniq face eliminarea duplicatelor numai daca liniile sunt sortate. Exemple de utilizare:

razvan@ragnarok:~/cfiles/solab/labs$ echo -en "alfa\nbeta\nbeta\nalfa\nbeta\ngamma\nalfa\n" | uniq
alfa
beta
alfa
beta
gamma
alfa
razvan@ragnarok:~/cfiles/solab/labs$ echo -en "alfa\nbeta\nbeta\nalfa\nbeta\ngamma\nalfa\n" | sort | uniq
alfa
beta
gamma
razvan@ragnarok:~/cfiles/solab/labs$ echo -en "alfa\nbeta\nbeta\nalfa\nbeta\ngamma\nalfa\n" | sort | uniq -c
      3 alfa
      3 beta
      1 gamma

wc

Comanda wc (word count) este folosita pentru a contoriza numarul de linii, de cuvinte sau de caractere dintr-un text sau de la intrarea standard. Pentru aceasta i se pot specifica optiunile -c, -w, -l.

cut

Comanda cut selecteaza numai anumite parti ale fisierului de intrare sau ale intrarii standard. Sintaxa cea mai folosita este:

cut -d delim -f fields

Folosindu-se delimitatorul delim se vor selecta numai campurile fields. Exemple de utilizare sunt:

razvan@ragnarok:~/cfiles/solab/labs$ ls -l
total 44
drwxr-xr-x  2 razvan razvan 4096 Nov 16 00:01 lab1
drwxr-xr-x  3 razvan razvan 4096 Oct 12 00:02 lab2
-rwxr-xr-x  1 razvan razvan  937 Oct 19 00:53 lab2html.sh
drwxr-xr-x  3 razvan razvan 4096 Oct 19 00:50 lab3
drwxr-xr-x  3 razvan razvan 4096 Oct 26 01:09 lab4
drwxr-xr-x  3 razvan razvan 4096 Nov  2 09:47 lab5
drwxr-xr-x  3 razvan razvan 4096 Nov 12 19:56 lab6
drwxr-xr-x  2 razvan razvan 4096 Nov 16 12:43 lab7
drwxr-xr-x  2 razvan razvan 4096 Nov 20 14:38 lab8
drwxr-xr-x  5 razvan razvan 4096 Oct 17 19:52 solab
drwxr-xr-x  2 razvan razvan 4096 Nov 12 20:06 tema1
razvan@ragnarok:~/cfiles/solab/labs$ ls -l | cut -d ' ' -f 1,9
total
drwxr-xr-x 00:01
drwxr-xr-x 00:02
-rwxr-xr-x 19
drwxr-xr-x 00:50
drwxr-xr-x 01:09
drwxr-xr-x 2
drwxr-xr-x 19:56
drwxr-xr-x 12:43
drwxr-xr-x 14:38
drwxr-xr-x 19:52
drwxr-xr-x 20:06
razvan@ragnarok:~/cfiles/solab/labs$ ls -l | tr -s ' ' | cut -d ' ' -f 1,9
total
drwxr-xr-x lab1
drwxr-xr-x lab2
-rwxr-xr-x lab2html.sh
drwxr-xr-x lab3
drwxr-xr-x lab4
drwxr-xr-x lab5
drwxr-xr-x lab6
drwxr-xr-x lab7
drwxr-xr-x lab8
drwxr-xr-x solab
drwxr-xr-x tema1

Comenzi din aceeasi categorie sunt paste si join.

Filtrarea pe baza de expresii regulate

Cele mai puternice utilitare pentru filtrarea textului in lumea UNIX sunt sed si awk. Acestea permit utilizatorilor sa editeze fisierele text si sa filtreze iesirea altor comenzi folosind expresii regulate.

Similaritati

Exista multe similaritati intre sed si awk:

Sintaxa

Sintaxa folosita pentru invocarea awk sau sed este:

command 'script' filenames

Aici command este awk sau sed, script este o insiruire de comenzi intelese de awk sau sed, iar filenames este lista de fisiere asupra carora se actioneaza. Daca nu se specifica nici un fisier, se foloseste intrarea standard. In acest fel putem utiliza awk si sed ca si filtre pentru iesirea altor comenzi.

Mod de rulare

Cand awk sau sed ruleaza, vor realiza urmatoarele operatii:

  1. se citeste o linie de la intrare
  2. se realizeaza o copie a acestei linii
  3. se executa script pe aceasta linie
  4. se repeta pasul 1 pentru urmatoare linie

Structura unui script

Structura unui script este de forma

/pattern/   action

Aici pattern este o expresie regulata, iar action este actiunea pe care fie awk, fie sed va trebui sa o execute cand se intalneste sablonul. Caracterele / din jurul expresiei regulate sunt folosite ca delimitatori.

Cand awk sau sed executa un script, foloseste urmatoarea procedura pentru fiecare inrregistrare:

  1. cauta secvential fiecare pattern din script pana cand se gaseste o potrivire
  2. cand se gaseste o potrivire, se executa actiunea action asupra liniei de intrare
  3. cand actiunea este completa, trece la urmatorul pattern si repeta pasul 1
  4. cand toate sabloanele au fost epuizate, se citeste urmatoarea linie
Inaintea ultimului pas (pasul 4) sed afiseaza inregistrarea modificata; in awk va trebui specificata functia de afisare.

Expresii regulate

Elementele de baza ale unei expresii regulate sunt:

Caractere obisnuite sunt litere, numere, sau caractere precum spatiu sau underscore. Metacaracterele sunt caractere care au un inteles special in cadrul unei expresii regulate. Ele sunt expandate in niste caractere obisnuite. Prin utilizarea metacaracterelor nu trebuie specificate toate combinatiile distincte de caractere pentru care vrei sa existe potrivire.

Metacaractere sunt:

Exemple

Fie pattern-ul

/peach/

Daca expresia este utilizata in sed sau awk atunci orice linie care contine acest sir este selectata. Dintre liniile care pot fi selectate, putem avea

we have a peach tree in the backyard
i prefer peaches to plums

Pattern-ul

/a.c/

se potriveste cu orice linie care contine siruri precum a+c, a-c, abc, match, a3c, in vreme ce pattern-ul

/a*c/

se potriveste cu sirurile de mai sus si, in plus, cu ace, yacc, arctic. De asemea se potriveste si cu linia

close the window

Se observa ca nu exista litera a in propozitie; aceasta din cauza ca * se potriveste cu 0 sau mai multe aparitii ale lui a.

Se observa ca expresiile regulate folosite in cadrul sed si awk sunt similare cu cele folosite de utilitarul lex (flex).

sed

sed inseamna stream editor. Citeste fiecare linie de la intrare si realizeaza un set de actiuni. Sintaxa de baza pentru sed este:

sed 'script' files

script este o secventa de comenzi de forma

/pattern/ action

pattern este o expresie regulata iar action poate avea una din formele de mai jos:

Vom exemplifica afisarea liniilor. Avem un fisier fruit_prices.txt. Dorim sa afisam informatii numai despre acele fructe care au pretul sub 1. Comenzile de executat sunt urmatoarele:

razvan@ragnarok:~/cfiles/solab/labs/lab8$ sed '/0\.[0-9][0-9]$/p' fruit_prices.txt
fruit           price
banana          0.89
banana          0.89
peach           0.79
peach           0.79
kiwi            1.50
pineapple       1.29
apple           0.99
apple           0.99
mango           2.20
razvan@ragnarok:~/cfiles/solab/labs/lab8$ sed -n '/0\.[0-9][0-9]$/p' fruit_prices.txt
banana          0.89
peach           0.79
apple           0.99

Se observa necesitatea folosirii optiunii -n. In mod obisnuit, sed afiseaza toate liniile de la intrare la iesire.

Daca dorim sa eliminam intrarea despre un fruct vom folosi comanda:

razvan@ragnarok:~/cfiles/solab/labs/lab8$ sed '/^[Mm]ango/d' fruit_prices.txt
fruit           price
banana          0.89
peach           0.79
kiwi            1.50
pineapple       1.29
apple           0.99

Se observa ca in cazul folosirii actiunii d nu mai este nevoie sa precizam optiunea -n.

Pentru substitutie de expresii regulate, sintaxa este

/pattern/s/pattern1/pattern2/

In acest caz, pattern1 este inlocuit cu pattern2 pentru toate liniile care se potrivesc cu pattern. Foarte frecvent pattern este omis.

Sa consideram urmatorul exemplu in care dorim sa inlocuim sirul eqal cu equal din cauza unor greseli de editare. Setul de comenzi de rulat este:

razvan@ragnarok:~/cfiles/solab/labs/lab8$ cat nash.txt
things that are eqal to the same thing are eqal to each other
razvan@ragnarok:~/cfiles/solab/labs/lab8$ sed 's/eqal/equal/' nash.txt
things that are equal to the same thing are eqal to each other
razvan@ragnarok:~/cfiles/solab/labs/lab8$ sed 's/eqal/equal/g' nash.txt
things that are equal to the same thing are equal to each other

Se observa ca in prima faza se producea inlocuirea numai a primei aparitii a lui pattern1. Pentru a se realiza inlocuirea tuturor aparitiilor s-a folosit optiune /g (global).

De multe ori va trebui sa folosim comenzi sed multiple (de forma /patttern/ action). Pentru aceasta folosim optiunea -e in forma

sed -e 'command1' -e 'command2' ... -e 'commandN' files

Din cauza ca sed citeste de la intrarea standard in lipsa unui fisier, poate fi folosit ca si filtru.

awk

awk este un limbaj de programare care permite cautarea in fisiere si modificarea inregistrarilor din aceste fisiere prin intermediul sabloanelor. Numele awk vine de la numele creatorilor sai: Alfred Aho, Peter Weinberger si Brian Kernighan.

Ca si la sed, sintaxa de baza este de forma:

awk 'script' files

script este o succesiune de comenzi de forma:

/pattern/ { actions }

pattern este o expresie regulata, iar actions reprezinta una sau mai multe comenzi care sunt acoperite in acest capitol. Daca se omite pattern, se aplica actiunile asupra fiecarei linii.

Spre exemplu, o implementare a lui cat folosind awk ar fi:

$ awk '{ print; }' file

Editarea campurilor

Cand se citeste o linie, awk plaseaza campurile care le-a parsat in variabila 1 pentru primul camp, variabila 2 pentru al doilea camp si asa mai departe. Pentru a accesa un camp, vom folosi operatorul $. Astfel primul camp este $1.

Un exemplu de utilizare este:

razvan@ragnarok:~/cfiles/solab/labs/lab8$ awk '{ print $1 $3 ; }' fruit_prices.txt
fruitquantity
banana100
peach65
kiwi22
pineapple35
apple78
mango34
razvan@ragnarok:~/cfiles/solab/labs/lab8$ awk '{ print $1 , $3 ; }' fruit_prices.txt
fruit quantity
banana 100
peach 65
kiwi 22
pineapple 35
apple 78
mango 34

Putem formata iesirea folosind comanda printf:

razvan@ragnarok:~/cfiles/solab/labs/lab8$ awk '{ printf "%-15s %s\n", $1 , $3 ; }' fruit_prices.txt
fruit           quantity
banana          100
peach           65
kiwi            22
pineapple       35
apple           78
mango           34

Actiuni specifice unor pattern-uri

Dorim sa indicam acele fructe care costa mai mult de 1 prin asezarea unei stelute la sfarsitul liniei. Avem urmatorul script:

razvan@ragnarok:~/cfiles/solab/labs/lab8$ cat highlight.sh
#!/bin/sh

awk '
        / *[1-9][0-9]*\.[0-9][0-9] */   { print $1, $2, $3, "*"; }
        / *0\.[0-9][0-9] */             { print ; }
' fruit_prices.txt
razvan@ragnarok:~/cfiles/solab/labs/lab8$ ./highlight.sh
banana          0.89            100
peach           0.79            65
kiwi 1.50 22 *
pineapple 1.29 35 *
apple           0.99            78
mango 2.20 34 *

Se observa ca avem o afisare necorespunzatoare. Pentru a evita aceasta situatie vom folosi variabila 0 care este folosita pentru a stoca intreaga linie asa cum fusese ea citita. Scriptul va arata in felul urmator:

razvan@ragnarok:~/cfiles/solab/labs/lab8$ cat highlight.sh
#!/bin/sh

awk '
        / *[1-9][0-9]*\.[0-9][0-9] */   { print $0, "*"; }
        / *0\.[0-9][0-9] */             { print ; }
' fruit_prices.txt
razvan@ragnarok:~/cfiles/solab/labs/lab8$ ./highlight.sh
banana          0.89            100
peach           0.79            65
kiwi            1.50            22 *
pineapple       1.29            35 *
apple           0.99            78
mango           2.20            34 *

Filtrarea intrarii standard

In lipsa unui fisier, awk foloseste intrarea standard si poate fi folosit ca si filtru. Daca dorim sa afisam numai numele si dimensiunea unui fisier vom folosi urmatoarea comanda.

Operatorul !~ este un operator boolean si intoarce true daca valoarea precizata (in acest caz primul camp) nu se potriveste cu pattern-ul (in acest caz total).

awk - limbaj de programare

Variabile

Definirea si utilizarea variabilelor in awk este similara cu cea din shell. Totusi, aici se face distinctia intre variabile numerice si siruri de caractere. Astfel, secventa de instructiuni:

a=1
b=a+1

Operatorii aritmetici sunt +, -, *, /, %, ^. La fel ca si in C, este permisa folosirea operatorului compus de forma +=, -=, *=, etc.

Sabloanele speciale: BEGIN si END

Daca dorim sa realizam anumite actiuni numai la inceputul sau la sfarsitul programului putem utiliza pattern-urile speciale BEGIN si END. In acest caz, forma generala pentru o comanda awk devine:

awk '
     BEGIN { actions }
     /pattern/ { actions }
     /pattern/ { actions }
     END { actions }
' files

Cand se precizeaza BEGIN, actiunile asociate acestuia vor fi executate inaintea citirii oricarei linii. Cand se precizeaza END, actiunile asociate vor fi executate inainte de iesire.

Variabile built-in

awk predefineste un set de variabile care pot fi folosite de utilizator. Acestea sunt:

Pentru a stabili un nou separator, putem utiliza optiunea -F sau putem specifica folosind o actiune la BEGIN. Cele doua exemple sunt prezentate mai jos:

$ awk 'BEGIN { FS='':'' ; } { print $1, $6 ; }' /etc/passwd
$ awk -F':'

Controlul fluxului

Exista trei forme principale de controlul fluxului if, for, while.

Sintaxa de baza pentru if:

if (expression) {
     action1
else {
     action2
}

Pentru while este:

while (expression)
     actions
}

Pentru for:

for (initialize_counter; test_counter; increment_counter) {
      action
}

Sintaxa pentru toate aceste comenzi este identica cu cea din C si permite o foarte mare flexibilitate utilizatorului.

De multe ori este util sa realizam un fisier separat pentru utilizarea unor comenzi awk. Pentru aceasta in loc de script in sintaxa de baza pentru awk vom folosi acel nume de fisier. Spre exemplu in loc de:

razvan@ragnarok:~/cfiles/solab/labs/lab8$ awk -F':' '
BEGIN { num = 0; }
/home/ { num += 1; }
END { print "Numarul total de utilizatori care au directorul de baza in /home este:", num; }
' /etc/passwd
Numarul total de utilizatori care au directorul de baza in /home este: 9

putem utiliza

razvan@ragnarok:~/cfiles/solab/labs/lab8$ cat passwd.awk
BEGIN   { num = 0; }
/home/  { num += 1; }
END     { print "Numarul de utilizatori care au directorul de baza in /home este ", num; }
razvan@ragnarok:~/cfiles/solab/labs/lab8$ awk -F':' -f passwd.awk /etc/passwd
Numarul de utilizatori care au directorul de baza in /home este  9

About this document ...

Programare shell: filtre de text, sed, awk

This document was generated using the LaTeX2HTML translator Version 2002-2-1 (1.71)

Copyright © 1993, 1994, 1995, 1996, Nikos Drakos, Computer Based Learning Unit, University of Leeds.
Copyright © 1997, 1998, 1999, Ross Moore, Mathematics Department, Macquarie University, Sydney.

The command line arguments were:
latex2html -split 0 -nosubdir -show_section_numbers lab8.tex

The translation was initiated by Razvan Adrian Deaconescu on 2005-11-20


next_inactive up previous
Razvan Adrian Deaconescu 2005-11-20