Twitter RSS
| |

Printre administratorii de sistem sau de retea e o moda sa cunosti cel putin un limbaj de scripting. De ce? Pentru ca flexibilitatea limbajelor de scripting usureaza foarte mult munca. Unul dintre limbajele de scripting cele mai folosite in UNIX e AWK si voi incerca sa fac o mica introducere in modul de utilizare a acestuia.

Ce este AWK?

AWK este un limbaj interpretat care ne usureaza munca. Numele lui vine de la initalele numelor autorilor ( Aho, Weinberger si Kernighan ). Punctul forte al acestui limbaj este usurinta cu care putem interpreta si prelucra textele putand foarte usor sa creem rapoarte, sa facem statistici si calcule matematice pe baza unui fisier text.
AWK poate fi folosit atat ca limbaj de scripting cat si ca si comanda.
Sa vedem cateva exemple care vor ajuta la formarea unei idei despre ce poate face acest limbaj.

a) Cautarea unui sir de caractere intr-un fisier text:
Folosim ca si exemplu fisierul /etc/passwd care este scris in text plan si cautam cuvantul ‘mail’. Cel mai simplu mod e sa facem asta din linia de comanda folosind urmatoarea sintaxa:

$ awk '/sir de cautat/' fisier.txt

In cazul nostru comanda si rezultatul sunt dupa cum urmeaza:

MyUser@server$ awk '/mail/' /etc/passwd
smmsp:*:25:25:Sendmail Submission User:/var/spool/clientmqueue:/usr/sbin/nologin
mailnull:*:26:26:Sendmail Default User:/var/spool/mqueue:/usr/sbin/nologin
MyUser@server$

Dupa cum vedeti AWK a parcurs fisierul /etc/passwd si a afisat liniile care contin cuvantul cautat, in cazul nostru cuvantul ‘mail’.

b) Cautarea unui sir si afisarea selectiva
Exemplul anterior nu arata nimic iesit din comun. E simplu de cautat un cuvant intr-un fisier in orice editor de texte care se respecta. Haideti sa vedem un exemplu mai complex in care nu ne mai putem folosi de un simplu editor de texte.
Pentru exemplificare folosesc un fisier, ip.txt, care tine datele in format TSV (Tab Separated Values). Fisierul are urmatorul continut:

33996344        33996351        GB      GBR     UNITED KINGDOM
50331648        69956103        US      USA     UNITED STATES
69956104        69956111        BM      BMU     BERMUDA
69956112        83886079        US      USA     UNITED STATES
94585424        94585439        SE      SWE     SWEDEN
100663296       121195295       US      USA     UNITED STATES
121195296       121195327       IT      ITA     ITALY
121195328       152305663       US      USA     UNITED STATES
152305664       152338431       GB      GBR     UNITED KINGDOM
152338432       167772159       US      USA     UNITED STATES
184549376       201674095       US      USA     UNITED STATES
201674096       201674111       CA      CAN     CANADA

Probabil unora vi se pare cunoscut fisierul. Pentru cei care nu stiti ce sunt liniile de mai sus, e vorba de o parte dintr-un fisier mai mare care contine IP-urile alocate fiecarei tari.
Bun, revenind la exemplul nostru, ne intereseaza grupurile de IP-uri corespunzatoare statelor unite. Cum ne poatem usura treaba folosind awk? Simplu, ii “spunem” ce anume sa caute ca in exemplul precedent:

MyUser@server$ awk '/UNITED STATES/' ip.txt
50331648        69956103        US      USA     UNITED STATES
69956112        83886079        US      USA     UNITED STATES
100663296       121195295       US      USA     UNITED STATES
121195328       152305663       US      USA     UNITED STATES
152338432       167772159       US      USA     UNITED STATES
184549376       201674095       US      USA     UNITED STATES
MyUser@server$

Nimic deosebit fata de celalalt exemplu, nu? OK, acum ne-am “prins” cum se pot selecta liniile corespunzatoare statelor unite, dar pe noi ne intereseaza doar primele doua coloane si nimic mai mult. Nu e nici o problema. Extindem putin comanda si din awk ‘/UNITED STATES/’ ip.txt o transformam in awk ‘/UNITED STATES/ {print $1,$2}’ ip.txt. Rezultatul afisat va fi dupa cum urmeaza:

MyUser@server$ awk '/UNITED STATES/ {print $1,$2}' ip.txt
50331648 69956103
69956112 83886079
100663296 121195295
121195328 152305663
152338432 167772159
184549376 201674095
MyUser@server$

Ce s-a intamplat, de fapt? awk a cautat in fisierul ip.txt toate liniile care contineau sirul de caractere ‘UNITED STATES’ iar apoi pentru fiecare linie gasita a aplicat regula {print $1,$2} care ii spune sa afiseze doar coloana 1 si 2. Dupa cum v-ati prins, cu simbolul dolar se specifica coloana care ne intereseaza. Daca ne interesau doar coloanele 3 si 4 foloseam in loc de {print $1,$2}, {print $3,$4} iar rezultatul afisat era format din 6 linii de forma: US USA.
De mentionat ca puteam lasa print fara nici un parametru dupa, adica doar {print}, caz in care era afisata intreaga linie ca si in primul exemplu dat. Acelasi lucru se intampla si daca ii spuneam interpretorului sa afiseze doar $0, pentru ca $0 retine intreaga linie citita.

Bun, am vazut cum se poate restrange rezultatul dar daca ne intereseaza sa punem conditii inainte de afisarea sau prelucrarea unei linii? Se poate si asta. In exemplul de mai sus sa presupunem ca ne intereseaza doar liniile care au pe prima coloana o valoare mai mica de 100000000. E la fel de simplu ca pana acum. Adaugam o simpla conditie, un if cu care probabil majoritatea sunteti obisnuiti din alte limbaje de programare/scripting. Codul de mai sus se transforma in awk ‘{ if($1<100000000) print $0}’ ip.txt iar exemplul practic e urmatorul:

MyUser@server$ awk '{ if($1<100000000) print $0}' ip.txt
33996344        33996351        GB      GBR     UNITED KINGDOM
50331648        69956103        US      USA     UNITED STATES
69956104        69956111        BM      BMU     BERMUDA
69956112        83886079        US      USA     UNITED STATES
94585424        94585439        SE      SWE     SWEDEN
MyUser@server$

Dupa cum se vede, conditia a fost aplicata cu succes si toate liniile care au pe prima coloana o valoare mai mica de 100000000 sunt afisate. Daca ne interesau doar rezultatele din statele unite, putem adauga din nou criteriul de sortare dupa cum am fost obisnuiti din exemplele anterioare:

MyUser@server$ awk '/UNITED STATES/ { if($1<100000000) print $0}' ip.txt
50331648        69956103        US      USA     UNITED STATES
69956112        83886079        US      USA     UNITED STATES
MyUser@server$

c) Contorizarea

Un alt exemplu de utilizare awk este contorizarea numarului de linii prezente intr-un fisier, functionalitate foarte utila in cazul generarii unor rapoarte. Sa ramanem la fisierul din exemplul anterior si sa vedem cum putem afla numarul de linii din fisier. Problema se rezolva in felul urmator:

MyUser@server$ awk 'END {print NR}' ip.txt
12
MyUser@server$

Da… e simplu. Am folosit END care este un termen nou si care merita putina atentie. Normal, un script AWK sau o comanda arata in felul urmator:

awk 'BEGIN
    primul_criteriu_de_cautare      {actiunile aplicate}
    al_doilea_criteriu_de_cautare   {actiunile aplicate}
    al_treilea_criteriu_de_cautare  {actiunile aplicate}
    al_patrulea_criteriu_de_cautare {actiunile aplicate}
    END {actiunile aplicate}'

Ce intelegem din asta? Un script e delimitat in mod normal de BEGIN care ne spune unde incepe scriptul si END care ne arata finalul scriptului. In exemplele de mai sus nu am folosit aceste doia cuvinte cheie pentru ca am folosit un singur criteriu de cautare si o actiune asociata caz in care BEGIN si END nu e obligatoriu sa apara.
Dupa cum va puteti da seama din exemplul de mai sus, intre BEGIN si END sunt puse mai multe linii, pe fiecare linie e specificat un criteriu de cautare/parcurgere a textului si un set de actiuni care se aplica liniilor gasite cu ajutorul criteriului specificat. Scriptul se termina la END, putand specifica de asemenea niste actiuni finale, actiuni care sunt specificate doar inainte de finalizarea comenzii.
Astfel, ca sa intelegeti ce exemplul de contorizare de mai sus, interpretorului i se da doar actiunea de final, actiunea care ia loc la finalizarea scriptului (de aici cuvantul END in comanda).
Ce inseamna awk ‘END {print NR}’ ip.txt? Interpretorul ia fiecare linie din ip.txt si verifica daca corespune cu o conditie data (in cazul nostru nici una) iar cand toate liniile au fost parcurse se aplica conditia de final, conditia de dupa END care in cazul nostru este {print NR}. NR este o valoare care se incrementeaza la fiecare linie citita de interpretor. Astfel, interpretorul citeste fisierul ip.txt si nu face nimic decat la sfarsit cand afiseaza valoarea NR care ne arata numarul de linii citite.

Probabil v-ati dat seama deja ca si rezultatul afisat poate fi personalizat. De exemplu, putem inlocui {print NR} cu {print NR,” linii citite”}, adica adaugam inca un sir de caractere care trebuie afisat, de data asta un sir constant de caractere nu o variabila sau constanta a programului. Rezultatul va fi urmatorul:

MyUser@server$ awk 'END {print NR, " linii citite"}' ip.txt
12  linii citite
MyUser@server$

Popularity: 9% [?]

Comentarii pentru “Tutorial AWK”

Ai intrebari?

Reclama
Categorii
Apache
Articole si tutoriale legate de serverul web Apache.
/articole-tutoriale-apache/

cPanel
Articole si tutoriale legate de utilizarea si administrarea sistemului de gestiune a serverelor de hosting, cPanel.
/articole-tutoriale-cpanel-whm/

DNS
Vezi toate articolele din categoria DNS
/dns-bind-domain-name-services/

Linux
Articole si tutoriale legate de Linux, sisteme BSD sau alte sisteme de operare din familia UNIX.
/articole-tutoriale-linux/

Mail
Vezi toate articolele din categoria Mail
/mail/

MySQL
Articole si tutoriale despre serverul de baze de date MySQL.
/articole-tutoriale-optimizare-mysql/

Perl
Vezi toate articolele din categoria Perl
/perl-practical-extraction-and-report-language/

PHP
Vezi toate articolele din categoria PHP
/php-language-hypertext-preprocessor/

Virtualizare
Articole si tutoriale despre virtualizare si sistemel virtuale create cu Xen sau OpenVZ.
/virtualizare-xen-openvz/

Web hosting
Articole despre serviciile de gazduire web, dedicate sau in regim shared.
/web-hosting/

Webmin / Virtualmin
Articole si tutoriale legate de sistemul de gestiune gratuit Webmin sau modulul Virtualmin.
/webmin-virtualmin/





Newsletter
LAMP Recomandã
NetHelp
SRV.ro
ABCDomenii