1. Scopul lucrãrii Lucrarea de fata continua prezentarea ultimelor doua utilitare soft din sistemul de operare Unix: grep si awk. 2. Consideratii teoretice 2.1. Familia de programe GREP Familia de programe grep ( Global Regular Expression Print) permite cãutarea unui sir, specificat printr-o expresie regulata, intr-o lista de fisiere. Rezultatul comenzii se poate afisa sau poate servi ca intrare pentru o alta comanda UNIX. Cele trei comenzi din familia grep sunt: grep, fgrep si egrep. Ele diferã prin generalitatea expresiei cãutate si prin viteza de cãutare. Comanda grep cautã expresii regulate specificate conform editorului ed, algoritmul de cãutare fiind compact si nedeterminist. Comanda fgrep ( Fast grep) cautã siruri fixe, algoritmul de cãutare fiind compact si rapid. Comanda egrep ( Extended Grep) cautã expresii regulate generalizate, algoritmul de cãutare fiind rapid si determinist. In mod normal se foloseste fgrep pentru cãutarea sirurilor fixe si egrep in caz contrar, cu exceptia cãutãrilor de siruri ce se repeta când se foloseste grep. Expresiile regulate folosite de grep folosesc '\(' si '\)' pentru a defini grupuri, fiind permisa cãutarea de grupuri ce se repeta. In schimb expresiile regulate folosite de egrep nu folosesc simbolul '\' la definirea grupurilor si nu permit cãutarea de gupuri ce se repeta. Sintaxa comenzilor: grep [optiuni] sir [fisier(e)] egrep [optiuni] [sir] [fisier(e)] fgrep [optiuni] [sir] [fisier(e)] Optiuni ce afecteazã cãutare : -w Cãutarea se face pe cuvânt ( BSD Unix). -v Selecteazã liniile care nu contin sirul. -i Tratare echivalenta a literelor mari si mici. Optiuni ce afecteazã iesirea: -c Se indica doar numãrul de linii gãsite. -l Se indica doar numele fisierelor ce contin sirul specificat. -n Pentru fiecare linie se indica numele fisierului si numãrul liniei. -s In versiunea V ( numai pentru grep) se suprima afisarea mesajelor de eroare. Comenzile fgrep si egrep admit optiunile: -e sir Se foloseste pentru cãutarea sirurilor ce încep cu '-'. -f fis Se citeste lista de expresii regulate din fis. Exemplu: fgrep "3242" studenti > gr3242 2.2. AWK Analog utilitarului GREP, AWK este un instrument pentru analiza si manevrarea usoara si eleganta a datelor. Versiunea originala a fost dezvoltata in 1977 de cãtre Alfred Aho, Peter Weinberger, and Brian Kernighan de la AT&T Bell Labs. O versiunea îmbunãtãtitã este operationala din 1985. Gawk este implementarea GNU a awk-ului (disponibila sub Linux). Aceasta se considera a fi compatibila versiunea 4 de Unix System V. In cele ce urmeazã utilitarul awk este tratat in general fãrã particularitãti specifice unei versiuni. Din acest motiv se recomanda înainte de scrierea unui program awk consultarea bibliografiei aferente. Exemplele ilustrate au fost testate si executate atât sub Linux cat si sub Unix SVR4. Un program AWK este format din mai multe comenzi. O comanda este formata la rândul ei dintr-un sablon de selectie si un bloc de actiune: selectie { actiune } Selectia se realizeazã prin folosirea expresiilor regulate. Actiunea are sintaxa apropiata C si permite efectuarea unor operatii pe datele din fisier. Un fisier este vãzut de un program awk ca fiind o succesiune de înregistrãri. Daca separatorul de înregistrare nu a fost modificat el având valoarea predefinitã, caracterul '\n', înregistrarea este identica cu linia. Înregistrarea este împãrtitã in câmpuri separatorul de câmpuri, FS, putând lua chiar si mai multe valori. 2.2.1. Sintaxa de apel Setul de sabloane împreuna cu actiunile formeazã un program awk, care poate fi specificat in cadrul liniei de comanda sau poate fi pãstrat intr-un fisier, fiind citit ulterior de un program awk. Sintaxa: awk -Fc [-f] <comanda_awk | program_awk> <fisier(e)> c -reprezinta caracterul separator de câmpuri (implicit \t si \b) comanda_awk este o linie de forma 'selectie { actiune } ' program_awk (obligatoriu .awk) succesiune de comenzi awk. fisier(e) - fisier(e) pe care se executa comanda sau comenzile awk. Fisierul standard de intrare se specifica prin '-'. Exemple de apeluri corecte: $awk '$6 > $4' divizia1 divizia2 ... $awk '$1 > 0 { print $1, "; cu TVA: " $1*1.18 }' 123 123; cu TVA: 145.14 -98 Ctrl-D $cat TVA.awk $1 > 0 { print $1, "; cu TVA: " $1*1.18 } $awk -f TVA.awk date.int # date.int = datele de intrare 2.2.2. Câmpuri si variabile Fiecare înregistrare este impartita in câmpuri, functie de valoarea variabilei predefinite FS. Acestea sunt referite prin $1, $2, ...; $0 reprezita înregistrarea curenta. Exista urmatoarele variabile predefinite in programele AWK: ARGC Numãrul argumentelor din linia de comanda. ARGV Sirul argumentelor din linia de comanda. Sirul este indexat de la 0 la ARGC 1. ENVIRON Sirul variabilelor din mediu. Sirul este indexat prin variabilele de mediu (de exemplu: ENVIRON["HOME"] poate fi /home/adi). FILENAME Numele fisierului de intrare curent. Daca nu este specificat nici un fisier in linia de comanda, valoarea variabilei FILENAME este ''. FNR (File Number Records) Numãrul inregistrarii curente citita din fisierul de intrare. FS (Field Separator) Separatorul de câmpuri la intrare, implicit '\b'. NF (Number of Fields) Numãrul de câmpuri din înregistrarea curenta. NR (Number of Records) Numãrul de înregistrãri inspectate. OFMT Formatul de iesire pentru numere, implicit "%.6g". OFS (Output Field Separator) separatorul de câmpuri la iesire, implicit '\b'. ORS (Output Record Separator) separatorul de înregistrare la iesire, implicit '\n'. RS (Record Separator) separator de înregistrare, implicit '\n'. Daca RS este setat la sirul null, atunci inregistrarile sunt separate prin linii blanc. In acest caz, caracterul '\n' este separatorul de câmpuri, indiferent de valoarea lui FS. RSTART Indexul primului caracter potrivit dintr-un apel al functiei match; 0 daca nu exista potrivire. RLENGTH Lungimea sirului potrivit prin functia match; (1) in caz ca nu exista potrivire. SUBSEP Caracterul folosit pentru a separa indici multipli la elemente de sir, implicit '\034'. De exemplu: #env.awk BEGIN { for ( i in ENVIRON) print i "=" ENVIRON[i] } $awk -f env.awk LOGNAME=root SHELL=/bin/bash HOSTNAME=local.lab_a25.upg-ploiesti.ro ... $awk '{ print NF, $1, $(NF-1), $NF }' divizia 8 Munchen 34000 Spectatori 8 Leverkusen 28000 Spectatori 8 HSV 29000 Spectatori 8 Stuttgart 25000 Spectatori 8 Bremen 30000 Spectatori 8 Frankfurt 27000 Spectatori $awk '{ print "Jocul:", NR, $1, $2, $3 }' divizia Jocul: 1 Munchen Sportul Jocul: 2 Leverkusen Steaua Jocul: 3 HSV Dinamo Jocul: 4 Stuttgart U.Cluj Jocul: 5 Bremen Politehnica Jocul: 6 Frankfurt Dortmund Variabilele utilizator din programele awk nu trebuie declarate, ele fiind declarate si initializate la prima folosire ( cu 0 variabilele numerice si cu "" variabile de tip sir de caractere). Valorile lor pot fi numere sau siruri, sau ambele, in functie de folosirea lor. De exemplu: # ex1.awk - aflarea numarului de victorii in deplasare. $6 > $4 { depl = depl + 1 } END { print depl, "victorie(i) in deplasare" $awk f ex1.awk divizia 1 victorie(i) in deplasare # ex2.awk - raport final asupra meciurilor din etapa anterioara. { sum = sum + $7 } END { print NR, "Jocuri " print "Nr.total spectatori: ", sum print "Media pe meci: ", sum/NR } $awk f ex2.awk divizia 6 Jocuri Nr.total spectatori: 173000 Media pe meci: 28833.3 2.2.3. Concatenarea sirurilor Concatenarea de siruri se poate evidentia pe urmatorul exemplu: # ex3.awk - echipele care au pierdut BEGIN { print "Urmatoarele echipe au pierdut: " } $4 > $6 { list = list $3 ", " } END { print list } $awk f ex3.awk divizia Urmatoarele echipe au pierdut: Sportul, Steaua, Politehnica, 2.2.4. Formatarea iesirii Formatarea iesirii se poate observa pe exemplele: $awk {printf("%20s: %6d Spectatori; %2d goluri\n", $1, $7, $4+$6) } divizia Munchen : 34000 Spectatori; 5 goluri Leverkusen : 28000 Spectatori; 3 goluri HSV : 29000 Spectatori; 4 goluri Stuttgart : 25000 Spectatori; 1 goluri Bremen : 30000 Spectatori; 3 goluri Frankfurt : 27000 Spectatori; 0 goluri $awk '{ printf("%s a jucat contra %s scor final:%2d:%2d\n", $1, $3, $4, $6) }' divizia Munchen a jucat contra Sportul scor final: 3: 2 Leverkusen a jucat contra Steaua scor final: 2: 1 HSV a jucat contra Dinamo scor final: 2: 2 Stuttgart a jucat contra U.Cluj scor final: 0: 1 Bremen a jucat contra Politehnica scor final: 2: 1 Frankfurt a jucat contra Dortmund scor final: 0: 0 AWK permite siruri unidimensionale cele multidimensionale putând fi simulate. Sirurile sunt indexate cu o expresie intre paranteze drepte ([ si ]). Daca expresia este o lista de expresii atunci sirul de indici este un sir ce consta din concatenarea valorilor fiecarei expresii, separate de valoarea variabilei SUBSEP. Aceasta facilitate este utilizata pentru simularea sirurilor cu mai multe dimensiuni. De exemplu: i = "A" ; j = "B" ; k = "C" x[i, j, k] = "hello, world\n" atribuie sirul dintre ghilimele elementului din sirul x, indexat de sirul "A\034B\034C". Operatorul special in poate fi utilizat in instructiuni de control if sau while pentru a decide daca un sir permite un indice de o anumita valoare. if (val in array) print array[val] Acesta poate fi, de asemenea, folosit in bucle for pentru a parcurge toate elementele sirului. Un element poate fi sters dintr-un sir folosind comanda delete. Pentru ca o variabila sa fie tratata ca numar se aduna 0 la ea, iar pentru a fi tratata ca sir se concateneaza cu sirul null. Pentru conversia unui sir la numar se foloseste functia atof. Un numar este convertit la sir folosind valoarea constantei CONVFMT ca sir de formatare pentru sprintf. 2.2.5. Sabloane de selectie si actiuni 2.2.5.1. Sabloane de selectie AWK este un limbaj orientat pe linie. Pentru fiecare înregistrare din intrare se executa in ordine toate comenzile din programul AWK. Sablonul de selectie este primul si apoi actiunea. Ambele pot lipsi, dar nu deodata. Daca sablonul de selectie lipseste, actiunea este executata pentru fiecare înregistrare, independent de continutul ei. Daca lipseste actiune vor fi afisate toate inregistrarile care satisfac sablonul de selectie. De exemplu, se considera fisierul divizia cu urmatorul continut: $cat divizia Munchen Sportul 3 : 2 34000 Spectatori Leverkusen Steaua 2 : 1 28000 Spectatori HSV Dinamo 2 : 2 29000 Spectatori Stuttgart U.Cluj 0 : 1 25000 Spectatori Bremen Politehnica 2 : 1 30000 Spectatori Frankfurt Dortmund 0 : 0 27000 Spectatori O selectie fara actiune ar putea fi: $awk '$4 > 2' divizia Munchen Sportul 3 : 2 34000 Spectatori sau o actiune fara selectie ar fi: $awk '{ print $1, "a inscris acasa " $4" goluri"}' divizia Munchen a inscris acasa 3 goluri Leverkusen a inscris acasa 2 goluri HSV a inscris acasa 2 goluri Stuttgart a inscris acasa 0 goluri Bremen a inscris acasa 2 goluri Frankfurt a inscris acasa 0 goluri O selectie cu actiune: $awk '$4 == $6 { print $1, "", $3, $4 ":" $6 }' divizia HSV Dinamo 2:2 Frankfurt Dortmund 0:0 O linie de comentariu incepe cu caracterul '#". Liniile vide pot separa instructiuni. O instructiune, in mod normal, se termina cu '\n', in afara cazurilor când linia este terminata cu , { ? : && si ||. O linie poate fi continuata pe urmatoarea daca este terminata cu caracterul '\'. Pe o linie pot exista mai multe instructiuni daca acestea sunt separate prin caracterul ';'. Un sablon de selectie AWK pot fi o constructie: BEGIN END /expresie regulata/ expresie relationala sablon && sablon sablon || sablon sablon ? sablon : sablon (sablon) ! sablon sablon1, sablon2 BEGIN si END sunt sabloane speciale care nu sunt aplicate pe intrare. Actiunile atasate mai multor sabloane BEGIN sau END sunt concatenate, ca si cum ele ar fi scrise intr-un singur bloc. Actiunile atasate unui sablon BEGIN sunt executate inainte de a citi o intrare, iar cele atasate unui sablon END la terminarea intrarii. Prima se utilizeaza des pentru initializarea variabilelor, definirea separatorilor, iar ultima la afisarea finala a rezultatelor pe ecran. Sabloanele BEGIN si END nu pot fi combinate cu alte sabloane in expresii si trebuie sa aiba atasate actiuni. Actiunile atasate sabloanelor ce contin expresii regulate sunt executate pentru fiecare linie care se potriveste cu expresia regulata. O expresie relationala poate folosi orice operatori C. AWK recunoaste operatorii limbajului C: - operatori de atribuire: =, +=, -=, *=, /= %=; - operatori aritmetici: +, -, *, /, %, ++, --; - operatori relationali: <, <=, ==, !=, >=, >; - operatori logici: !, ||, &&. In operatiile de cãutare se folosesc des operatorii: ~ si !~. Primul semnifica coincidenta, iar al negarea sa. De exemplu: $3~/^Da/ # selecteaza campul trei care incepe cu sirul "Da" Expresia sablon1, sablon2 este un sablon ce permite o selectie ce incepe cu linie selectata de sablon1 si continua pana la linia selectata de sablon2, inclusiv. 2.2.5.2. Actiuni Instructiunile ce stabilesc actiunile sunt incluse intre acolade. Ele constau din instructiuni uzuale de atribuire, de test si de ciclare existente in majoritatea limbajelor. Operatorii, instructiunile de control si cele de I/E sunt asemanatoare cu cele din C. Instructiunile de control sunt: if (conditie) instructiune [ else instructiune ] while (conditie) instructiune do instructiune while (conditie) for (expr1; expr2; expr3) instructiune for (var in array) instructiune break continue delete array[index] exit [ expresie ] { instructiuni } Exemple: # if.awk BEGIN { print "Pentru LoTo rezultatele sunt:"} { if ( $4 > $6 ) printf( "\t1") else if ( $4 == $6 ) printf("\t0") else printf("\t2") } END { printf("\n") } $awk f if.awk divizia Pentru LoTo rezultatele sunt: 1 1 0 2 1 0 # lotto.awk BEGIN { srand() } { if ( $1>=$2) { printf(" %d din %d \n", $2, $1) for ( i in nrlotto) delete nrlotto[i] nr=0 while ( ++z<=$2) { do { numar=int( rand()*$1) + 1 } while ( numar in nrlotto) nrlotto[numar]=numar } for ( i=1; i<=$1; i++) if ( i in nrlotto) printf("%5d", i) printf("\n") } } $cat loto.txt 49 6 $awk f lotto.awk loto.txt 6 din 49 2 8 26 31 32 49 Instructiuni de I/E sunt: close(file) Inchide fisier ( pipe). getline Seteaza $0 la urmatoarea înregistrare din intrare. Seteaza NF, NR, FNR. getline var Seteaza var la urmatoarea înregistrare din intare. Seteaza NF, FNR. next Termina procesarea inregistrarii curente. print Afiseaza înregistrarea curenta. print lexpr Afiseaza lista de expresii. printf fmt, lexpr Formateaza si afiseaza. system( cmdline) Executa comanda si intoarce starea de exit. Este permisa redirectarea simpla si cu adaugare a operatiilor de I/E cu fisiere. Pentru pipe se poate folosi simbolul '|' ( este permisa linia cda | getline). Comanda getline va returna 0 la terminarea fisierului si (-1) in caz de eroare. Se permite folosirea functiilor printf si sprintf. 2.2.6. Functii predefinite 2.2.6.1. Functii numerice atan2( y, x) arctg(y/x) (in radiani). cos(x) cos(x). exp(x) exponential. int(x) trunchiaza la intreg. log(x) logaritm natural. rand() numar aleator din intervalul [0,1]. sin(x) sin(x). sqrt(x) radical. srand(x) numar aleator in [0,x]. Daca x lipseste se foloseste timpul curent. 2.2.6.2. Functii pe siruri gsub(r, s, t) Substituie global orice subsir, identificat de expresia regulata r, din t cu sirul s si returneaza numãrul de substitutii. Daca t lipseste subsitutia se aplica pe $0. Exemplu: gsub(/rot/,"read") gsub(/a/,"&l&,"canada") index( s, t) Returneaza indexul sirului t in sirul s, 0 daca t nu este subsir a lui s. Exemplu: print index("Rokkoko","ko") length( s) Returneaza lungimea sirului s sau lungimea lui $0, daca s lipseste. Exemplu: print length("Hallo") match( s, r) Returneaza pozitia din s in care apare expresia regulata s sau 0 daca r nu este prezenta. Pozitioneaza constantele RSTART and RLENGTH. Exemplu: BEGIN { name="schoschonen" x=match( name, /scho[n]*/) print x, RSTART, RLENGTH, substr( name, RSTART, RLENGTH) } $awk -f f.awk 1 1 4 scho split(s, a, r) Imparte sirul s functie de separatorul r si distribuie campurile in sirul a. Daca r lipseste se foloseste separatorul FS. Exemplu: BEGIN { strl=split("28.MAI.1994 Ora12:34", data,"[ .:]") print "Lungimea sirului:", strl print "data[1]=" data[1] print "data[2]=" data[2] print "data[3]=" data[3] print "data[4]=" data[4] print "data[5]=" data[5] } $awk -f data.awk Lungimea sirului: 5 data[1]=28 data[2]=MAI data[3]=1994 data[4]=Ora12 data[5]=34 sprintf(fmt,l) Afiseaza sirul din lista l conform formatului fmt. sub(r, s, t) Analog gsub, dar substituie prima aparitie. substr( s,i,n) Returneaza sirul de n caractere ce incepe la pozitia i in sirul s. Daca n este omis se returneaza restul caracterelor. tolower(s) Converteste caracterele sirului s la litere mici. toupper(s) Converteste caracterele sirului s la litere mari. Exemplu: # implementarea comenzii Unix wc printr-un program awk { nc = nc + length($0) + 1 nw = nw + NF } END { print NR, "Rinduri", nw, "Cuvinte", nc, "Caractere"} #awk f func.awk divizia 6 Rinduri 48 Cuvinte 258 Caractere 2.2.7. Functii utilizator Un program AWK poate contine pe linga secventa de perechi sablon-actiune, optional, definitii de functii utilizator. O functie utilizator poate fi definita intr-un program AWK oriunde e permisa o pereche sablon-actiune. Definitia unei functii trebuie prefixata de cuvantul cheie function sau func. function nume_functie( lista_de_param) { instructiuni } Apelul se face prin numele functiei. Parametrii actuali din apelul functiei substituie prin valoare parametrii formali declarati ( Call-by-value). Variabilele locale unei functii sunt declarate ca parametri suplimentari in lista_de_param. Conventia este separarea variabilelor locale de parametrii reali prin spatii suplimentare. De exemplu: function f(p, q, a, b) { # a, b sunt variabile locale ..... } /abc/ { ... ; f(1, 2) ; ... } De exemplu, pentru a extrage luna dintr-o data calendaristica se poate folosi functia luna: BEGIN { data1="20.7.80"; luna1=luna( data1) print luna1 " (" data1 ")" luna2=luna("20.August.1989") print luna2 } func luna( d) { pct=index( d, ".") d=substr( d, pct+1) pct=index( d, ".") return substr( d, 1, pct1) } $awk f luna.awk 7 (20.7.80) August Functiile se pot apela recursiv. De exemplu, pentru a inversa fiecare linie dintr-un fisier se poate scrie o functie inv. Programul awk este: $cat inv.awk { printf("|"); inv( $0 "\n"); printf("|\n"); } function inv( str) { if ( substr( str, 1, 1) != "\n") { printf("%s", substr( str, 1, 1)) inv( substr( str, 2)) printf("%s", substr( str, 1, 1)) } else printf("|<>|") } $cat fis Otto joaca lotto $awk -f inv.awk fis |Otto joaca lotto|<--->|ottol acaoj ottO| 3. Aplicatii 3.1. Sa se scrie un program awk care sa afiseze pentru un utilizator numele sau complet, directorul propriu, identificatorul utilizator si de grup.
# finger.awk BEGIN { FS=":" name=ARGV[1] ARGV[1]="/etc/passwd" } $5~name { printf("\n%s >login: %s\n", $5, $1) printf(" (home directory= %s; user id=%d; group id=%d)\n", $6, $3, $4); } $awk -f finger.awk adi adi kacso >login: adi (home directory= /home/adi; user id=504; group id=100) 3.2. Se considera existenta unui fisier conf cu numele tuturor conferintelor din anul in curs. Pentru fiecare conferinta se mentioneaza orasul si tara unde are loc conferinta. Sa se scrie un fisier de comenzi care sa permita selectia conferintelor dintr-o tara.
echo n "Numele fisierului rezultat: " direct=`pwd` read fis || break rep=0 while test $rep = 0 do echo n "Tara: FR IT GB RO: " read tara || break ref=${direct}/conf fout=${fis}_conf echo "Fisierul rezultat = $fout " grep "$tara" $ref > $fout echo n "O alta selectie [0/1=exit] ? " read rep || break done echo "OK fisierul a fost creat." 3.3. Sa se scrie un program awk care, folosind filtrul find si alte comenzi Unix, calculeaza numãrul de linii din fiecare fisier C intalnit in directorul ( sau directoarele) de cãutare primit ca argument in linia de comanda.
#clc dire=${@:`pwd`} find $dire name "*.c" exec wc l {} \; | awk ' { total += $1; printf("%40s : %7d\n", $2, $1) } END { printf("\n") printf("%40s : %7d\n", "Total", total) } ' $clc $HOME /home/adi/TCPtecho2.c : 51 /home/adi/m/TCPecho.c : 71 ... /home/adi/lib/connectsock.c : 77 /home/adi/TCPtecho.c : 135 /home/adi/TCPtecho1.c : 78 Total : 454 3.4. Sa se scrie un program awk, care primind ca intrare un fisier cu numere asezate sub forma unui tabel, acesta sa efectueze suma elementelor de pe fiecare coloana.
{ for (i=1; i<=NF; i++) sum[i] += $i if ( NF > max_col) max_col = NF print "\t" $0 } END { sum_txt="Suma:" for ( i=1; i<=max_col; i++) sum_txt = sum_txt "\t" sum[i] print print sum_txt } $awk f sum.awk calcul 12 47 25 150 23 10 20 12 15 30 Suma: 202 90 37 15 3.5. Sa se scrie un program awk care primind ca intrare rezultatul comenzii Unix ps sa afiseze un arbore cu procesele din sistem ( optiunile folosite la comanda ps sunt cele existente in Linux).
ps lexw | awk ' BEGIN { FS = "[ \t]+" slash[0]="|" ; rad=0 count[0]=0 " *sched( root=0, ?)" } NR==1 { cmd_pos=index( $0, "COMMAND") tty_pos=index( $0, "TTY") } NR!=1 { s = ++nr_fiu[$5] fiu[ $5, s] = $4 if ( $4 == 0) rad=$4 else if ( $5==0) mark[++x]=$4 count[$4]=$4 " *" substr( $0, cmd_pos, 30) count[$4]=count[$4] " (" $3", "substr($0,tty_pos,5) ")" } END { t=0; print count[ 0] for ( i in mark) prel( mark[i]) } function prel( i, r, j) { for ( r=0; r<t; r++) printf(" %s", slash[r]) printf(" |\n") for ( r=0; r<t; r++) printf(" %s", slash[r]) printf(" +%s\n", count[i]) t++ for ( j=1; j<=nr_fiu[i]; j++) { slash[ t]= (j < nr_fiu[i]) ? "|" : " " prel( fiu[i,j]); } t }' $pstree 0 *sched( root=0, ?) | +1 *init (0, ? ) | | | +6 *bdflush (daemon) (0, ? ) | | | +7 *update (bdflush) (0, ? ) | | | +40 */usr/sbin/syslogd (0, ? ) | | | +42 */usr/sbin/klogd (0, ? ) | | | +44 */usr/sbin/inetd (0, ? ) | | | +46 */usr/sbin/lpd (0, ? ) | | | +49 */usr/sbin/crond (0, ? ) | | | +53 *selection t ms (0, ? ) | | | +54 *bash (0, v01 ) | | | | | +183 *bash (0, v01 ) | | | | | +184 *ps lexw (0, v01 ) | | | | | +185 *awk BEGIN { FS = "[ \t]+" (0, v01 ) | | | +55 *bash (504, v02 ) | | | +56 *bash (501, v03 ) | | | | | +160 *joe test.c (501, v03 ) | | . . . | +59 */sbin/agetty 38400 tty6 (0, v06 ) 4. Probleme propuse 4.1. Ce afiseaza liniile de program awk: a) n = 5; print $n b) $cat f1 aaa bbb ccc# ddd# eee fff# ggg ttt# ggg eee# ccc ddd sss# yyy $cat exsplit.awk { i = split($0, Art,"#"); for( j=1; j<=i; j++) print("Art["j"] = ", Art[j]); } $awk -f exsplit.awk f1 c) $awk $6 > $4 { print $3, "a cistigat la " $1} divizia d) $awk '{ printf("%20s: %6d Spectatori, %2d goluri\n", $1, $7, $4+$6) }' divizia e) $grep '[Uu]nix' ch?/* 4.2. Se considera: $cat f2 sss aaa ina dan 1 ada sss ina dan 2 ada adi sss dan 3 ada adi ina sss 4 ttt adi ina dan 5 ada ttt ina dan 6 a) Ce afiseaza linia ? $awk '$3~/sss/, $2~/ttt/ { print ($0); }' f2 b) Ce diferenta exista intre rezultatele programelor awk ? $cat f3.awk $3 ~/sss/, $2 ~/ttt/ { print($0); } $1 ~/sss/, NR=5 { print($0,"*"); } $cat f4.awk $3 ~/sss/, $2 ~/ttt/ { print($0); next; } $1 ~/sss/, NR=5 { print($0,"*"); next; } 4.3. Sa se scrie un program awk care sa permita afisarea rezultatelor din fisierul divizia sub forma: Oaspeti Gazde | Rezultat + Munchen Sportul | 3 : 2 ... 4.4. Sa se scrie un program awk care sa permita conversia unui numar inrteg, primit ca argument in linia de comanda in hexazecimal si octal. 4.5. Sa se scrie un fisier de comenzi care afiseaza un tabel cu toate numele de login din sistem împreuna cu identificatorul utilizator atasat. 4.6. Se da un fisier de intrare care contine articole sub forma: <nume student># nota1# [nota2#] [nota3] <NL> <nume student>... Parantezele drepte marcheaza optionalitatea. Se cere sa se scrie un program awk care afiseaza un tabel cu antetul: Nume student Nota1 Nota2 Nota3 Media In tabel se vor gasi studentii, ordonati alfabetic care au toate notele si pentru care a fost calculata media. Studentii ramasi vor putea fi afisati la cerere. Sa se scrie un filtru care sa afiseze numele acelor studenti care au media > 8 si primele doua note minim 8. 4.7. Un fisier de intare are structura: Nume Prenume Tesa|Muncitor Salariu Sa se scrie un program awk care determina varsta si salariul mediu pe categorii de personal, precum si persoanele cu salariul minim si maxim. 4.8. Sa se afiseze intr-un tabel cu antet numele fisierului, i-node-ul asociat lui si data la care a fost creat fisierul. 4.9. Sa se scrie un program AWK care prelucreaza 4 fisiere in care sunt reprezentate matrici 4x4. Programul obtine matricea care are coloanele formate din diagonalele matricilor de intrare. 4.10. Se considera urmatorul program awk pentru rezolvarea problemei celor opt dame:
BEGIN { for ( i=1; i<=8; i++) collib[i] = 1 for ( i=2; i<=16; i++) ds[i] = 1 for ( i=7; i<=7; i++) dp[i] = 1 regina_pe() } Sa se scrie functia regina_pe, care sa permita obtinerea tuturor solutiilor. Pentru a vizualiza plasarea damelor pe tabla se va scrie o functie afis. 4.11. Sa se scrie un program awk, care primind ca intrare un fisier text cu randuri mai lungi de 40 de caractere il rescrie pe randuri de 30 de caractere. |