Awk este un limbaj de scripting de uz general conceput pentru procesarea avansată a textului. Este folosit mai ales ca instrument de raportare și analiză.spre deosebire de majoritatea celorlalte limbaje de programare care sunt procedurale, awk este bazat pe date, ceea ce înseamnă că definiți un set de acțiuni care trebuie efectuate împotriva textului de intrare. Ia datele de intrare, le transformă și trimite rezultatul la ieșirea standard.acest articol acoperă elementele esențiale ale limbajului de programare awk., Cunoașterea elementelor de bază ale awk vă va îmbunătăți semnificativ capacitatea de a manipula fișierele text pe linia de comandă.
cum funcționează awk #
există mai multe implementări diferite ale awk. Vom folosi implementarea GNU a awk, care se numește gawk. Pe majoritatea sistemelor Linux, interpretorul awk
este doar un simbol pentru gawk
.
înregistrări și câmpuri #
Awk poate procesa fișiere și fluxuri de date textuale. Datele de intrare sunt împărțite în înregistrări și câmpuri. Awk funcționează pe o singură înregistrare la un moment dat până când se ajunge la sfârșitul intrării., Înregistrările sunt separate printr-un caracter numit separator de înregistrare. Separatorul implicit de înregistrare este caracterul newline, ceea ce înseamnă că fiecare linie din datele de text este o înregistrare. Un nou separator de înregistrări poate fi setat folosind variabila RS
.
înregistrările constau din câmpuri care sunt separate de separatorul de câmp. În mod implicit, câmpurile sunt separate de un spațiu alb, inclusiv unul sau mai multe file, spațiu și caractere newline.
câmpurile din fiecare înregistrare sunt menționate de semnul dolarului ($
) urmat de numărul câmpului, începând cu 1., Primul câmp este reprezentat cu $1
, al doilea cu $2
și așa mai departe. Ultimul câmp poate fi de asemenea referit cu variabila specială $NF
. Întreaga înregistrare poate fi referită cu $0
.
Aici este o reprezentare vizuală care arată cum să referință, înregistrări și câmpuri:
tmpfs 788M 1.8M 786M 1% /run/lock /dev/sda1 234G 191G 31G 87% /|-------| |--| |--| |--| |-| |--------| $1 $2 $3 $4 $5 $6 ($NF) --> fields|-----------------------------------------| $0 --> record
Awk program #
Pentru a procesa un text cu awk
, scrie un program care spune comandă ce să fac., Programul constă dintr-o serie de reguli și funcții definite de utilizator. Fiecare regulă conține un model și o pereche de acțiuni. Regulile sunt separate prin newline sau semi-colons (;
). De obicei, un awk programul arată astfel:
pattern { action }pattern { action }...
awk
date de proces, dacă modelul corespunde record, se efectuează acțiunea specificată la înregistrare. Când regula nu are un model, toate înregistrările (liniile) sunt potrivite.
o acțiune awk este închisă în bretele ({}
) și constă în declarații., Fiecare declarație specifică operația care trebuie efectuată. O acțiune poate avea mai mult de o declarație separată prin linie nouă sau semi-colon (;
). Dacă regula nu are nicio acțiune, este implicit să imprimați întreaga înregistrare.Awk acceptă diferite tipuri de declarații, inclusiv expresii, condiționale, declarații de intrare, ieșire și multe altele. Cele mai frecvente declarații awk sunt:
-
exit
– oprește executarea întregului program și iese., -
next
– oprește procesarea înregistrării curente și trece la următoarea înregistrare din datele de intrare. -
print
– înregistrări de imprimare, câmpuri, variabile și text personalizat. -
printf
– Ofera mai mult control asupra formatului de ieșire, similar cu C și bashprintf
.
când scrieți programe awk, totul după marcajul hash (#)
și până la sfârșitul liniei este considerat a fi un comentariu., Liniile lungi pot fi împărțite în mai multe linii folosind caracterul de continuare, backslash (\
).
executarea programelor awk #
un program awk poate fi rulat în mai multe moduri. În cazul în care programul este scurt și simplu, acesta poate fi trecut direct la awk
interpret pe linia de comandă:
awk 'program' input-file...
atunci Când rulează programul pe linia de comandă, ar trebui să fie închise în ghilimele simple (''
), deci, shell-ul nu se interpreteze program.,
în Cazul în care programul este de mare și de complexă, cel mai bine este să-l pună într-un fișier și de a folosi -f
opțiunea de a trece la fișierul awk
command:
awk -f program-file input-file...
În exemplele de mai jos, vom folosi un fișier numit „echipe.txt ” care arată ca cel de mai jos:
Bucks Milwaukee 60 22 0.732 Raptors Toronto 58 24 0.707 76ers Philadelphia 51 31 0.622Celtics Boston 49 33 0.598Pacers Indiana 48 34 0.585
Awk Patterns #
modelele din awk controlează dacă acțiunea asociată trebuie executată sau nu.,Awk acceptă diferite tipuri de modele, inclusiv expresia regulată, expresia relației, gama și modelele speciale de Expresie.
când regula nu are un model, fiecare înregistrare de intrare este potrivită. Aici este un exemplu de o regulă care conțin numai o acțiune:
awk '{ print $3 }' teams.txt
programul va imprima cel de-al treilea câmp al fiecărei înregistrări:
6058514948
expresie Regulată modele #
O expresie regulată sau regex este un model care se potrivește cu un set de siruri de caractere., Awk expresie regulată modele sunt închise într-slash (//
):
/regex pattern/ { action }
Cele mai de bază exemplu este un literal caracter sau șir de potrivire. De exemplu, pentru a afișa primul câmp al fiecărei înregistrări care conține „0.5” ai executați următoarea comandă:
awk '/0.5/ { print $1 }' teams.txt
CelticsPacers
modelul poate fi orice tip de extins expresie regulată., Aici este un exemplu care imprimă primul câmp dacă înregistrarea începe cu două sau mai multe cifre:
awk '/^/ { print $1 }' teams.txt
76ers
Relaționale expresii modele #
relaționale expresii modele sunt utilizate în general pentru a se potrivi conținutul de un anumit câmp sau variabilă.
în mod implicit, modelele de expresii regulate sunt potrivite cu înregistrările. Pentru a potrivi un regex cu un câmp, specificați câmpul și utilizați operatorul de comparație „contain”(~
) împotriva modelului.,
De exemplu, pentru a imprima primul câmp al fiecărei înregistrări al doilea câmp conține „ia” ai fi de tip:
awk '$2 ~ /ia/ { print $1 }' teams.txt
76ersPacers
Pentru a se potrivi domenii care nu conțin un anumit model de a folosi !~
operator:
awk '$2 !~ /ia/ { print $1 }' teams.txt
BucksRaptorsCeltics
puteți compara siruri de caractere sau numere de relații, cum ar fi, mai mare decât, mai mic decât, egal, și așa mai departe., Urmatoarea comanda printuri primul câmp din toate înregistrările a căror treilea domeniu este mai mare decât 50:
awk '$3 > 50 { print $1 }' teams.txt
BucksRaptors76ers
Gama de modele #
Gama de modele constau din două modele separate prin virgulă:
pattern1, pattern2
Toate înregistrările care încep cu o înregistrare care se potrivește cu primul model, până când o înregistrare care se potrivește cel de-al doilea model se potrivesc.,
Aici este un exemplu care va imprima primul câmp din toate înregistrările pornind de la înregistrare, inclusiv „Raptor” până când înregistrarea inclusiv „Celtics”:
awk '/Raptors/,/Celtics/ { print $1 }' teams.txt
Raptors76ersCeltics
modele pot fi, de asemenea, legate de expresii. Comanda de mai jos va imprima toate înregistrările pornind de la cel al cărui al patrulea domeniu este egal cu 32 până la cel al cărui al patrulea domeniu este egal cu 33:
awk '$4 == 31, $4 == 33 { print $0 }' teams.txt
76ers Philadelphia 51 31 0.622Celtics Boston 49 33 0.598
Gama de modele nu poate fi combinat cu un alt model de expresii.,Awk include următoarele pattens speciale:
-
BEGIN
– folosit pentru a efectua acțiuni înainte ca înregistrările să fie procesate. -
END
– folosit pentru a efectua acțiuni după procesarea înregistrărilor.
BEGIN
model este folosit în general pentru a seta variabile și END
model pentru a procesa datele din înregistrări, cum ar fi de calcul.
următorul exemplu va tipări ” începeți procesarea.”, apoi imprimați cel de-al treilea câmp al fiecărei înregistrări și în final „procesarea finală.,”:
awk 'BEGIN { print "Start Processing." }; { print $3 }; END { print "End Processing." }' teams.txt
Start Processing6058514948End Processing.
Dacă un program are doar un BEGIN
model, acțiunile sunt executate, și de intrare nu este procesat. Dacă un program are doar un model END
, intrarea este procesată înainte de a efectua acțiunile regulii.
versiunea Gnu a awk include, de asemenea, două modele speciale BEGINFILE
și ENDFILE
, care vă permite să efectuați acțiuni, atunci când prelucrarea fișierelor.,Awk vă permite să combinați două sau mai multe modele folosind operatorul logic și (&&
) și operatorul logic sau (||
).,
Aici este un exemplu care folosește &&
operator pentru a imprima prima terenul celor de înregistrare al cărui al treilea domeniu este mai mare decât 50 și cel de-al patrulea domeniu este mai mică decât 30:
awk '$3 > 50 && $4 < 30 { print $1 }' teams.txt
BucksRaptors
Built-in Variabile #
Awk are un număr de built-in de variabile care să conțină informații utile și vă permite să controlați modul în care programul este procesat. Mai jos sunt câteva dintre cele mai comune variabile încorporate:
-
NF
-numărul de câmpuri din înregistrare., -
NR
– numărul înregistrării curente. -
FILENAME
– numele fișierului de intrare care este procesat în prezent. -
FS
– separator de câmp. -
RS
– separator de înregistrare. -
OFS
– separator de câmp de ieșire. -
ORS
– separator de înregistrare de ieșire.,
Aici este un exemplu care arată cum să imprimați numele fișierului și numărul de linii (înregistrări):
awk 'END { print "File", FILENAME, "contains", NR, "lines." }' teams.txt
File teams.txt contains 5 lines.
Variabile în AWK poate fi setat la orice linie din program. Pentru a defini o variabilă pentru întregul program, puneți-o într-un model BEGIN
.
schimbarea separatorului de câmp și înregistrare #
valoarea implicită a separatorului de câmp este orice număr de caractere de spațiu sau tab. Acesta poate fi modificat prin setarea în variabila FS
.,
De exemplu, pentru a seta domeniul de separare a .
v-ar folosi:
awk 'BEGIN { FS = "." } { print $1 }' teams.txt
Bucks Milwaukee 60 22 0Raptors Toronto 58 24 076ers Philadelphia 51 31 0Celtics Boston 49 33 0Pacers Indiana 48 34 0
separator de câmp poate fi de asemenea setat la mai multe caractere:
awk 'BEGIN { FS = ".." } { print $1 }' teams.txt
atunci Când rulează awk unul-garnituri pe linia de comandă, puteți utiliza, de asemenea, -F
opțiunea de a schimba domeniul de separare:
awk -F "." '{ print $1 }' teams.txt
în mod implicit, record separator este un caracter newline și poate fi schimbată folosind RS
variabilă.,
Aici este un exemplu care arată cum să schimbi discul separator pentru .
:
awk 'BEGIN { RS = "." } { print $1 }' teams.txt
Bucks Milwaukee 60 22 0732 Raptors Toronto 58 24 0707 76ers Philadelphia 51 31 0622Celtics Boston 49 33 0598Pacers Indiana 48 34 0585
Awk Acțiuni #
Awk acțiuni sunt închise în acolade ({}
) și executat atunci când modelul se potrivește. O acțiune poate avea zero sau mai multe declarații. Mai multe declarații sunt executate în ordinea în care apar și trebuie să fie separate prin linie nouă sau semi-colons (;
).,există mai multe tipuri de declarații de acțiune care sunt acceptate în awk:
- expresii, cum ar fi atribuirea variabilă, operatorii aritmetici, operatorii de creștere și decrementare.
- declarații de Control, utilizate pentru a controla fluxul de program (
if
,for
,while
,switch
, și mai mult) - Ieșire declarații, cum ar fi
print
șiprintf
. - declarații compuse, pentru a grupa alte declarații.,
- declarații de intrare, pentru a controla procesarea de intrare.
- Declarații de ștergere, pentru a elimina elementele de matrice.
declarația print
este probabil cea mai utilizată declarație awk. Se imprimă o ieșire formatat de text, înregistrări, câmpuri, și variabile.când imprimați mai multe articole, trebuie să le separați cu virgule., Aici este un exemplu:
awk '{ print $1, $3, $5 }' teams.txt
imprimate elemente sunt separate prin câte un singur spații:
Bucks 60 0.732Raptors 58 0.70776ers 51 0.622Celtics 49 0.598Pacers 48 0.585
Dacă nu utilizați virgule, nu va fi nici un spațiu între elementele:
awk '{ print $1 $3 $5 }' teams.txt
elementele imprimate sunt concatenate:
Bucks600.732Raptors580.70776ers510.622Celtics490.598Pacers480.585
print
este folosit fără un argument, implicit print $0
. Înregistrarea curentă este tipărită.,
Pentru a imprima un text personalizat, trebuie să cităm textul cu dublu-citat de caractere:
awk '{ print "The first field:", $1}' teams.txt
The first field: BucksThe first field: RaptorsThe first field: 76ersThe first field: CelticsThe first field: Pacers
de asemenea, puteți imprima caractere speciale, cum ar fi newline:
awk 'BEGIN { print "First line\nSecond line\nThird line" }'
First lineSecond lineThird line
printf
declarație vă oferă mai mult control asupra formatului de ieșire., id=”aa8cfd3cbd”>
printf
nu crea o linie nouă după fiecare înregistrare, astfel încât suntem folosind \n
:
1. Bucks Milwaukee 60 22 0.732 2. Raptors Toronto 58 24 0.707 3. 76ers Philadelphia 51 31 0.622 4. Celtics Boston 49 33 0.598 5. Pacers Indiana 48 34 0.585
comanda următoare calculează suma valorilor stocate în cel de-al treilea câmp din fiecare linie:
awk '{ sum += $3 } END { printf "%d\n", sum }' teams.txt
266
Aici este un alt exemplu care arată cum să folosească expresii și declarații de control pentru a imprima pătrate de numere de la 1 la 5:
awk 'BEGIN { i = 1; while (i < 6) { print "Square of", i, "is", i*i; ++i } }'
Square of 1 is 1Square of 2 is 4Square of 3 is 9Square of 4 is 16Square of 5 is 25
O linie de comandă, cum ar fi cea de mai sus sunt mai greu de înțeles și de întreținut., Când scrieți programe mai lungi, ar trebui să creați un fișier de program separat:
BEGIN { i = 1 while (i < 6) { print "Square of", i, "is", i*i; ++i } }
Rulați programul prin care trece un nume de fișier pentru awk
interpret:
awk -f prg.awk
puteți rula, de asemenea, un awk program ca un executabil cu ajutorul tacamului directivă și setarea awk
interpret:
#!/usr/bin/awk -fBEGIN { i = 1 while (i < 6) { print "Square of", i, "is", i*i; ++i } }
Salvați fișierul și să-l executabil :
chmod +x prg.awk
acum puteți rula programul prin introducerea:
./prg.awk
Folosind Shell Variabile în Awk Programe #
Dacă utilizați awk
comanda in shell script-uri, șansele sunt că veți avea nevoie pentru a trece un shell variabilă la awk program. O opțiune este să închideți programul cu dublu în loc de ghilimele unice și să înlocuiți variabila din program., Cu toate acestea, această opțiune va face programul awk mai complex, deoarece va trebui să scăpați de variabilele awk.modul recomandat de a utiliza variabilele shell în programele awk este de a atribui variabila shell unei variabile awk. Iată un exemplu:
num=51
awk -v n="$num" 'BEGIN {print n}'