|
|
Dit artikel is beschikbaar in: English Castellano ChineseGB Deutsch Francais Italiano Nederlands Turkce |
door Javier Palacios Bermejo Over de auteur: Onze geachte schrijver verkiest zijn publiekelijke leven met mysterie te omhullen. Vandaar dat hij anoniem blijft. Inhoud: |
Kort:
Dit artikel geeft inzicht in de trucs die je met AWK kan uithalen. Het is geen
cursus maar levert echte, bruikbare voorbeelden.
sed
en grep
) te krijgen.
Hamvraag hier is of het commando echt bruikbaar is. Het antwoordt is een
volmondig Ja!! Het kan bruikbaar zijn voor doorsnee gebruikers voor het
bewerken van tekstbestanden, het opnieuw opmaken etc... AWK is echter
écht belangrijk voor de systeembeheerder. Snuffel eens wat in
/var/yp/Makefile
of bekijk de initialisatie scripts van een
willekeurig systeem. AWK is overal.
Mijn eerste ervaring met AWK stamt uit een ver verleden. Ik had een collega
die moest werken met heel veel uitvoer van een kleine Cray. De helppagina over
awk
op de Cray was zeer summier, maar hij dacht dat het was wat
hij hiervoor nodig had, hoewel hij nog geen flauw idee had hoe het te
gebruiken.
Later in mijn leven was er een andere collega die AWK gebruikte om de eerste
kolom uit een tabel te halen:
awk '{print $1}' file
Simpel hè? Deze eenvoudige taak hoeft niet, moeilijk moeilijk, in een
complexe taal als C te worden geprogrammeerd, noch in enige andere
gecompileerde of geïnterpreteerde taal. Eén regel awk
doet het 'm.
Na de les een kolom extraheren kunnen we overgaan naar zoiets als het
hernoemen van bestanden:
ls -1 pattern | awk '{print "mv "$1" "$1".new"}' | sh
...en er is meer. Het gebruik van sed
of grep
, in
combinatie met het laatste voorbeeld, is een nog krachtiger hulpmiddel.
ls -1 *old* | awk '{print "mv "$1" "$1}' | sed s/old/new/2 | sh
rm
te gebruiken, maar wat dan in het geval van een alias
als rm -r
)
ls -l * | grep -v drwx | awk '{print "rm "$9}' | sh
ls -l | grep '^d' | awk '{print "rm -r "$9}' | sh
ls -p | grep /$ | wk '{print "rm -r "$1}'
)
Indien we bijvoorbeeld bepaalde herhaalde berekeningen uit moeten voeren met wisselende parameters en we willen daarbij een aantal uitvoerbestanden selecteren voor verdere verwerking, dan kan dit hulpmiddel echt van dienst zijn. ...Nog afgezien van het feit dat het veel leuker is om een AWK-programma te schrijven dan het herhaaldelijk intikken van (bijna) hetzelfde commando.
Feitelijk, hoewel we het normaal gesproken zo benoemen, is awk
nou
niet echt wat we ons voorstellen van een commando. awk
is een
programmeertaal met een syntaxis die erg lijkt op C. Het is een
geïnterpreteerde taal en de awk
-interpretator verwerkt de
instructies.
Over de syntaxis van het commando zelf:
# gawk --help Usage: gawk [POSIX or GNU style options] -f progfile [--] file ... gawk [POSIX or GNU style options] [--] 'program' file ... POSIX options: GNU long options: -f progfile --file=progfile -F fs --field-separator=fs -v var=val --assign=var=val -m[fr] val -W compat --compat -W copyleft --copyleft -W copyright --copyright -W help --help -W lint --lint -W lint-old --lint-old -W posix --posix -W re-interval --re-interval -W source=program-text --source=program-text -W traditional --traditional -W usage --usage -W version --version Report bugs to [email protected], with a Cc: to [email protected]In plaats van het simpelweg aanhalen (') van het programma op de commandoregel, kunnen we dit programma ook in een bestand zetten en het aanroepen met de
-f
optie. Met het gebruik van variabele definities als
-v var=val, kunnen we verdere flexibiliteit toevoegen aan de door
ons te schrijven programma's.
AWK is min of meer een taal, toegespitst op het werken met tabellen. Dat is informatie die kan worden gegroepeerd in velden en records. Het grote voordeel hier is dat de definitie van het record (en ook van de velden) zeer flexibel kan zijn.
Maar awk
is krachtig. Het is gemaakt voor het werken met records
van één regel, hoewel hieraan nog wel wat valt te doen. Om een
goed beeld te kunnen krijgen van dit soort aspecten, gaan we een aantal
praktische voorbeelden behandelen ter illustratie.
LaTeX
of, op zijn minst, in een
mooiere opmaak. Als het een eenvoudige tabel betreft (en/of we kennen
awk
heel goed) dan is het niet zo moeilijk.
BEGIN { printf "LaTeX preample" printf "\\begin{tabular}{|c|c|...|c|}" } |
{ printf $1" & " printf $2" & " . . . printf $n" \\\\ " printf "\\hline" } |
END { print "\\end{document}" } |
awk
gebruikt voor het opdelen van de grote
hoeveelheid uitvoer. Uiteraard moest ik hierbij gebruik maken van bepaalde
karakteristieken in de uitvoer.
|
( $1 == "====>" ) { NomObj = $2 TotObj = $4 if (TotObj > 0) { FS = "|" for (cont=0; cont<TotObj; cont++) { getline print $2 $4 $5 $3 >> NomObj } FS = " " } } |
Let op: in de praktijk werd de naam van het object niet geretourneerd en het lag allemaal wat gecompliceerder maar dit is dan ook slechts een voorbeeld ter illustratie. |
BEGIN { BEGIN_MSG = "From" BEGIN_BDY = "Precedence:" MAIN_KEY = "Subject:" VALIDATION = "[MONTH REPORT]" HEAD = "NO"; BODY = "NO"; PRINT="NO" OUT_FILE = "Month_Reports" } { if ($1 == BEGIN_MSG) { HEAD = "YES"; BODY = "NO"; PRINT="NO" } if ($1 == MAIN_KEY) { if ($2 == VALIDATION) { PRINT = "YES" $1 = ""; $2 = "" print "\n\n"$0"\n" > OUT_FILE } } if ($1 == BEGIN_BDY) { getline if ($0 == "") { HEAD = "NO"; BODY = "YES" } else { HEAD = "NO"; BODY = "NO"; PRINT="NO" } } if (BODY == "YES" && PRINT == "YES") { print $0 >> OUT_FILE } } |
Stel:we beheren een mailinglijst en af en toe
wordt er een speciaal bericht op de lijst gepost (een maandelijks overzicht
bijvoorbeeld) met een bepaalde vaste opmaak (het subject-veld
bijvoorbeeld als:
[MONTHREPORT} month, dept). Opeens besluiten we om een
eindejaarsoverzicht te maken met daarin een samenvatting van al de overzichten
(daarbij de rest negerend). Dat kan door de mail spool te bewerken met het awk
programma, zoals gegeven in de linkerkolom.
Om ieder overzicht in een apart bestand te krijgen moeten er drie extra regels code worden toegevoegd. |
Let op: dit voorbeeld gaat er vanuit dat de mail spool is opgezet zoals ik denk dat het is opgezet. Eigenlijk ken ik het echte formaat niet. Maar dit werkt op mijn machine (zoals altijd: in speciale gevallen zou het fout kunnen gaan). |
Ik heb awk
voor veel doeleinden gebruikt (bijvoorbeeld voor het
automatisch genereren van web pagina's met gegevens uit eenvoudige databases)
en ik weet inmiddels voldoende van het programmeren in awk
om te
kunnen stellen dat je er heel veel taken mee kunt doen.
De enige grens is je fantasie.
awk
is wellicht niet zo krachtig als andere hulpmiddelen die
speciaal voor dit doel zijn ontworpen. Maar het heeft het grote voordeel dat je
met een klein programmaatje snel een hulpmiddel kunt maken dat volledig de
behoefte dekt.
AWK is zeer geschikt voor het doel waarvoor het gemaakt is: data regel voor regel inlezen en deze data bewerken naar gelang de inhoud en patronen van die regel.
Bestanden als /etc/passwd blijken ideaal voor bewerking met AWK. Het is hierbij onmisbaar.
Uiteraard is er meer dan alleen AWK. Perl is een geduchte concurrent, maar het
is nog steeds nuttig om een paar awk
-trucs te kennen.
awk
is niet voor iedere *nix hetzelfde, maar
er is een manier om er achter te komen op ons eigen systeem:man awk
gawk
richt. En nog zo'n half dozijn andere titels.
|
Site onderhouden door het LinuxFocus editors team
© Javier Palacios Bermejo, FDL LinuxFocus.org Klik hier om een fout te melden of commentaar te geven |
2002-06-08, generated by lfparser version 2.28