AWK filtravimo pavyzdžiai
Windows aplinkoje AWK galite naudoti įdiegę Cygwin. Siųstis čia.
Šioje medžiagoje naudojamos kelios sąvokos: laukai (stulpeliai) ir įrašai (eilutės). Naudojantis šia Excel analogija yra šiek tiek lengviau suprasti kuo skiriasi ir kaip naudojami laukai ir įrašai.

Kas yra AWK
Bandysime naudojant AWK išmokti atlikti failų informacijos filtravimą, sudarant įvairaus sudėtingumo šablonus, išmokti naudoti UNIX programuojamą komandą awk, susipažinti su scenarijų failų paskirtimi ir sudarymo principais.
Awk komanda turi programavimo kalbos požymių, kurie leidžia atrinkti daugelį failų, pagal užduotus šablonus, ir modifikuoti juos nesirūpinant apie failų atidarymą, nuskaitymą ir uždarymą. Ši komanda yra sutinkama visuose UNIX versijose, yra gana lengvai suprantama, bei ypatingai lanksti.
Bendra programos paleidimo struktūra yra tokia: awk ‘komanda‘ failai
Pavyzdžiuose naudojamus failus ex_files_awk_esst atsiųsite iš čia.
1. pavyzdys – filtravimas pagal žodį
awk '/up/{print "UP: ", NF, $0}
/up/ – tekstinis filtras, ieško žodžio UP, skiriama su /tekstas/
NF – skaičiuoja žodžius eilutėje
“UP: “ – Išves į ekraną UP:
awk ‘/up/{print “UP: “, NF, $0}’ dukeofyork.txt
UP: 10 He marched them up to the top of the hill UP: 8 And when they were up they were up UP: 7 And when they were only half-way up UP: 6 They were neither up nor down
Išveda: žodį UP: pradžioje suskaičiuoja žodžius eilutėje ir parašo eilutės tekstą.
2. pavyzdys – failo atidarymas
awk -f swap.txt
-f – mažoji f vėliava nurodo, kad bus vykdomas failas swap.txt
awk -f swap.txt Galloway Gretchen Steele Isaac Myers Wayne Lee Lillith Blackwell Molly Arnold Maia Reese Lev Guthrie Carlos Buck Sophia
3. pavyzdys – filtravimas skiriant laukus specifiniu simboliu
awk -F , '{print $2}'
-F – didžioji F nurodo, koks simbolis skirs laukus. Šiuo atveju kabelis.
Rašoma: -F ,
awk -F , '{print $2}'
one,two,three
two
Išveda būtent antrame lauke esantį žodį: two
4. pavyzdys – filtravimas laukus skiriant su tabuliacijos simboliu
awk -F '\t' '{print $2}'
-F ‘\t’ – didžioji nurodo, kad laukus skirs vienas tabuliacijos simbolis, kitose sistemose veikia ir tik (–F t) tačiau šiuo atveju reikėjo pilno (-F ‘\t’)
awk -F '\t' '{print $2}'
one two three
two
Išveda būtent antrame lauke esantį žodį: two
5. pavyzdys – duomenų išvedimas naudojant kintamuosius
awk -v hi=HELLO '{print $1, hi}'
-v hi=HELLO – v vėliavėlė nurodo, kad bus naudojamas kintamasis hi, kurį nurodysime spausdindami
print $1, hi – būtent ir nurodome, kad spausdinsime pirmą lauke ir iš karto po jo mūsų kintamąjį hi, kuris yra lygus HELLO
awk -v hi=HELLO '{print $1, hi}'
hello awk
hello HELLO
nice to meet you
nice HELLO
burokas
burokas HELLO
Išveda pirmą lauke esantį žodį ir prie jo prirašo žodį HELLO
6. pavyzdys – filtruoti eilutes, kuriuos gali būti atskirtos keliais skirtingais simboliais
awk -F '[,!]' '{print $2}'
-F ‘[,!]’ – atskirti žodžiams lauke galima naudoti ir kelis simbolius iš karto. Šiuo atveju naudojame kablelį ir šauktuką. Juos aprašant būtinai reikia naudoti tokią formą ‘[,!]’
awk -F '[,!]' '{print $2}'
one!two,three
two
one,two!three
two
Išveda būtent two kadangi abiem atvejais atpažino, kad antras žodis yra two
7. pavyzdys – naudojame struktūra Begin ir laukų kintamąjį FS
AWK kintamasis FS – laukų (stolpelių) skyriklio kintamasis
awk 'BEGIN{FS=","} {print $2}'
BEGIN{FS=”,”} – yra universalesnis būdas atpažinti skyrikliams tarp įrašų.
Jeigu nori naudoti viską vienos laužtiniuose skliaustose turime rašyti ‘{FS=”,”; print $2}’ t.y. viską atskirti kabliataškiu
awk 'BEGIN{FS=","} {print $2}
one,two,three
two
Papildomai, galime naudoti kelis simbolius rašant juos [ ] skliaustuose.
awk 'BEGIN{FS="[,!?]"} {print $2}'
one!two?three two
8. pavyzdys – AWK kintamasis RS – įrašų (eilučių) skyriklio kintamasis
cat onebigline.txt
one,two,three!four,five,six!seven,eight,nine!ten,eleven,twelve
awk 'BEGIN{RS="!"; FS=","} {print $0}'
‘BEGIN{RS=”!”; – RS nurodo, kad šauktuko simbolis pradeda naują eilutę arba nauja įrašą
FS=”,” – tuo tarp FS nurodo, kad skyriklis yra kablelis ir taip bus atskiriami laukai
print $0 – jeigu $0 spausdina viską
awk 'BEGIN{RS="!"; FS=","} {print $0}' onebigline.txt
one,two,three
four,five,six
seven,eight,nine
ten,eleven,twelve
Vieną eilutę, tvarkingai surikiuoja į atskiras eilutes, kadangi jos buvo atskirtos šauktuko simboliu.
awk 'BEGIN{RS="!"; FS=","} {print $2}' onebigline.txt
two
five
eight
eleven
Kadangi print $2 pasirinkome antrą lauką, mums ir išveda visų eilučių antrus laukus
9. pavyzdys – praktinis RS ir FS skyriklių panaudojimas.
Turime failą moltiaddress.txt su tokiu turiniu. Ir norime viską atrinkti tik vardus, kurie yra pirmoje kiekvieno adreso eilutėje.
cat moltiaddress.txt Gladys Rim 322 New Horizon Blvd Milwaukee, WI 53207 Yuki Whobrey 1 State Route 27 Taylor, MI 48180 Fletcher Flosi 394 Manchester Blvd Rockford, IL 61109 Bette Nicka 6 S 33rd St Aston, PA 19014 Veronika Inouye 6 Greenleaf Ave San Jose, CA 95111 Willard Kolmetz 618 W Yakima Ave Irving, TX 75062
awk 'BEGIN{RS="";FS="\n"} {print $1}'
RS=””; – įrašų (eilučių) kintamasis nurodomas “” t.y. jokio simbolio
\n – naujos eilutės žymėjimas
FS=”\n” – nurodomas, kaip laukų skyriklis yra nurodoma nauja eilutė
awk 'BEGIN{RS="";FS="\n"} {print $1}' moltiaddress.txt
Gladys Rim
Yuki Whobrey
Fletcher Flosi
Bette Nicka
Veronika Inouye
Willard Kolmetz
Kiekviena nauja informacijos eilutė įrašoma į atskirą lauką (stolpelį), kadangi RS nedaro jokios įtakos filtravimui, gauname tokį rezoltatą.
10. pavyzdys – teksto išfiltravimas į vieną eilutę su RS ir FS
Naudodami tą patį duomenų failą su RS ir FS pagalba surašome visus įrašus į vieną eilutę naudodami kintamuosius.
cat moltiaddress.txt Gladys Rim 322 New Horizon Blvd Milwaukee, WI 53207 Yuki Whobrey 1 State Route 27 Taylor, MI 48180 Fletcher Flosi 394 Manchester Blvd Rockford, IL 61109 Bette Nicka 6 S 33rd St Aston, PA 19014 Veronika Inouye 6 Greenleaf Ave San Jose, CA 95111 Willard Kolmetz 618 W Yakima Ave Irving, TX 75062
awk 'BEGIN{RS="";FS="\n"} {name=$1;adress=$2;other=$3; print name "," address " "other}'
FS=”\n” – kaip ir ankstesniame pavyzdyje kiekviena nauja eilutė priskiria naują lauką
name=$1;adress=$2 – naudodami savo sugalvotus kintamuosius priskiriame jiems stolpelių pavadinimus
print name “,” address – spausdiname norimus stolpelius naudodami kintamuosius, juos papildomai atskiriame kableliais ir tarpais
awk 'BEGIN{RS="";FS="\n"} {name=$1;adress=$2;other=$3; print name "," address " "other}' moltiaddress.txt
Gladys Rim , Milwaukee, WI 53207
Yuki Whobrey, Taylor, MI 48180
Fletcher Flosi, Rockford, IL 61109
Bette Nicka, Aston, PA 19014
Veronika Inouye, San Jose, CA 95111
Willard Kolmetz, Irving, TX 75062
11. pavyzdys – išvesties kintamieji OFS ir ORS ir jų pritaikymas
FS ir RS yra įvesties kintamieji, tai pat yra galimybė atlikti teksto filtravimą tiesiog išvedant informaciją su OFS lauko (stulpelio) ir ORS įrašo (eilutės) kintamaisiais. Šiame pavyzdyje išfiltruosime tekstą ir apjungsime jį vieną eilutę. Naujos eilutės pradžia atskirsime šauktuku, o naują stulpelį atskirsime kableliu
cat names.txt Gretchen Galloway Isaac Steele Wayne Myers Lillith Lee Molly Blackwell Maia Arnold Lev Reese Carlos Guthrie Sophia Buck Vincent Mitchell Buffy Harris Reuben Miles Brendan Fowler Mason Hancock Nigel Boone Gretchen Foreman Serena Goodman Shoshana Velez Eve Hughes
Komanda:
awk 'BEGIN{OFS=", "; ORS="!"} {print $2, $1}' names.txt
OFS=”, “; – išveda naują lauką (stolpelį) su kabeliu ir tarpu
ORS=”!”} – išveda naują įrašą (eilutę) su šauktuku
awk 'BEGIN{OFS=", "; ORS="!"} {print $2, $1}' names.txt
Galloway, Gretchen!Steele, Isaac!Myers, Wayne!Lee, Lillith!Blackwell, Molly!Arnold, Maia!Reese, Lev!Guthrie, Carlos!Buck, Sophia!Mitchell, Vincent!Harris, Buffy!Miles, Reuben!Fowler, Brendan!Hancock, Mason!Boone, Nigel!Foreman, Gretchen!Goodman, Serena!Velez, Shoshana!Hughes, Eve!
12. pavyzdys – išfiltruosime tekstą ir žodžius skiriančius kablelius pakeisime tabuliacijos tarpais
Turime failą nameemailavg.csv kuriame kiekvienoje eilutėje yra atskirti duomenis kableliais. Išfiltruosime šį tekstą, kad būtų viskas atskirta TAB simboliu.
cat nameemailavg.csv Art Venere,art@venere.org,256.62394383 Lenna Paprocki,lpaprocki@hotmail.com,259.688783099 Donette Foller,donette.foller@cox.net,282.32979844 Simona Morasca,simona@morasca.com,139.51911647 Dominque Dickerson,dominque.dickerson@dickerson.org,167.045197551 Leota Dilliard,leota@hotmail.com,253.646335223 Sage Wieser,sage_wieser@cox.net,155.55576823 Kris Cho,kris@gmail.com,210.794277775 Minna Amigon,minna_amigon@yahoo.com,95.47955397 Abel Maclead,amaclead@gmail.com,225.774477397 Kiley Caldarera,kiley.caldarera@aol.com,172.957628871 Graciela Ruta,gruta@cox.net,202.68364784 Josephine Darakjy,josephine_darakjy@darakjy.org,178.877840188 Cammy Albares,calbares@gmail.com,290.446513401 Mattie Poquette,mattie@aol.com,283.23995223 Meaghan Garufi,meaghan@hotmail.com,227.142916195 Gladys Rim,gladys.rim@rim.org,243.459635712 Yuki Whobrey,yuki_whobrey@aol.com,128.321717297 Fletcher Flosi,fletcher.flosi@yahoo.com,221.394141603
Kodas:
awk 'BEGIN{FS=",";OFS="\t"} {print $1,$2,$3}' nameemailavg.csv
FS=”,”; – nustatome, kad laukai yra atskirti kablelio simboliu
OFS=”\t” – iššvęsti nustatome, kad tai bus su taboliacijos simboliu
awk 'BEGIN{FS=",";OFS="\t"} {print $1,$2,$3}' nameemailavg.csv
Art Venere art@venere.org 256.62394383
Lenna Paprocki lpaprocki@hotmail.com 259.688783099
Donette Foller donette.foller@cox.net 282.32979844
Simona Morasca simona@morasca.com 139.51911647
Dominque Dickerson dominque.dickerson@dickerson.org 167.045197551
Leota Dilliard leota@hotmail.com 253.646335223
Sage Wieser sage_wieser@cox.net 155.55576823
Kris Cho kris@gmail.com 210.794277775
Minna Amigon minna_amigon@yahoo.com 95.47955397
Abel Maclead amaclead@gmail.com 225.774477397
Kiley Caldarera kiley.caldarera@aol.com 172.957628871
Graciela Ruta gruta@cox.net 202.68364784
Josephine Darakjy josephine_darakjy@darakjy.org 178.877840188
Cammy Albares calbares@gmail.com 290.446513401
Mattie Poquette mattie@aol.com 283.23995223
Meaghan Garufi meaghan@hotmail.com 227.142916195
Gladys Rim gladys.rim@rim.org 243.459635712
Yuki Whobrey yuki_whobrey@aol.com 128.321717297
Fletcher Flosi fletcher.flosi@yahoo.com 221.394141603
13. pavyzdys – panaudosime integruotos kintamuosius NR, FILENAME ir FNR
awk '{print NR, FILENAME, FNR, $0}' dukeofyork.txt names.txt
NR – parodo įrašo (eilutės) numerį
FILENAME – parodo apdorojamo įrašo failo pavadinimą
FNR – parodo faile esančio įrašo eilutės numerį
awk '{print NR, FILENAME, FNR, $0}' dukeofyork.txt names.txt
1 dukeofyork.txt 1 The grand old Duke of York
2 dukeofyork.txt 2 He had ten thousand men
3 dukeofyork.txt 3 He marched them up to the top of the hill
4 dukeofyork.txt 4 And he marched them down again
5 dukeofyork.txt 5 And when they were up they were up
6 dukeofyork.txt 6 And when they were down they were down
7 dukeofyork.txt 7 And when they were only half-way up
8 dukeofyork.txt 8 They were neither up nor down
9 names.txt 1 Gretchen Galloway
10 names.txt 2 Isaac Steele
11 names.txt 3 Wayne Myers
12 names.txt 4 Lillith Lee
13 names.txt 5 Molly Blackwell
14. pavyzdys – panaudosime NF kintamąjį, suskaičiuosime kiek eilutėje yra laukų
NF kintamasis suskaičiuoja kiek laukų yra vienoje eilutėje. Jį galima panaudoti norint išfiltruoti patį paskutinį žodį eilutėje, nes jis sutaps su žodžių kiekiu.
$ cat dukeofyork.txt The grand old Duke of York He had ten thousand men He marched them up to the top of the hill And he marched them down again And when they were up they were up And when they were down they were down And when they were only half-way up They were neither up nor down
Kodas:
awk '{print "Viso laukų:",NF, "Paskutinis žodis:", $NF }' dukeofyork.txt
“Viso laukų:”,NF, – išspausdinta tekstą ir suskaičiuoja laukų skaičių
“Paskutinis žodis:”, $NF – išspausdinta tekstą ir išvedą paskutinį žodį, kadangi jis sutampa su žodžių kiekių eilutėje.
awk '{print "Viso laukų:",NF, "Paskutinis žodis:", $NF }' dukeofyork.txt
Viso laukų: 6 Paskutinis žodis: York
Viso laukų: 5 Paskutinis žodis: men
Viso laukų: 10 Paskutinis žodis: hill
Viso laukų: 6 Paskutinis žodis: again
Viso laukų: 8 Paskutinis žodis: up
Viso laukų: 8 Paskutinis žodis: down
Viso laukų: 7 Paskutinis žodis: up
Viso laukų: 6 Paskutinis žodis: down
$(NF-1) – sėkmingai galime naudoti ir aritmetinius veiksmus norėdami išfiltruoti prieš paskutinį žodį, tai yra iš žodžių kiekio atimame vieną ir gauname priešpaskutinio lauko padėtį.
awk '{print "Viso laukų:",NF, "Prieš paskutinis žodis:", $(NF-1)}' dukeofyork.txt
Viso laukų: 6 Prieš paskutinis žodis: of
Viso laukų: 5 Prieš paskutinis žodis: thousand
Viso laukų: 10 Prieš paskutinis žodis: the
Viso laukų: 6 Prieš paskutinis žodis: down
Viso laukų: 8 Prieš paskutinis žodis: were
Viso laukų: 8 Prieš paskutinis žodis: were
Viso laukų: 7 Prieš paskutinis žodis: half-way
Viso laukų: 6 Prieš paskutinis žodis: nor
15. pavyzdys – spausdinsime failo dukeofyork.txt pirmą eilutę skirtingais būdais
Atspausdinsime failo dukeofyork.txt pirmą eilutę naudodami keletą skirtingų komandų variacijų:
awk '{print $1}' dukeofyork.txt
awk '{printf ("%s\n", $1)}' dukeofyork.txt
printf (“%s\n”, – antrame pvz. naudojamas printf , sutrumpintai print format, kuris suteikia platesnes galimybes formatuoti tekstą.
Šiuo atveju abi komanda išveda tekstą vienodai:
The He He And And And And They
16. pavyzdys – naudosime filtravimo su simboliais logiką
Kai ketvirtas laukas yra up tuomet bus spausdinama eilutė
awk '$4 ~ /up/{print}' dukeofyork.txt
He marched them up to the top of the hill
They were neither up nor down
^ – pradžia – $ pabaiga
- /^abc/ filtruos “abcd”
- /^abc/ nefiltruos “dabc”
- /abc$/ nefiltruos “abcd”
- /abc$/ filtruos “dabc”
Atspausdina tik tas trečias eilutes, kurios prasideda su the
awk '$3 ~ /^the/{print}' dukeofyork.txt
He marched them up to the top of the hill
And when they were up they were up
And when they were down they were down
And when they were only half-way up
17. pavyzdys – IF ir ELSE naudojimas ir skripto paruošimas/paleidimas
IF ir Else naudojimas AWK filtravime. AWK skripto failų naudojimas ir paleidimas iš failo su –f ir su sh .
awk '{ if ( NF < 8 ) { print "short line:", $0} else { print "long line: ", $0} }'
if ( NF < 8 ) – suskaičiuoja laukų skaičių ir jeigu teiginys yra TRUE spausdina, laukų skaičius mažiau už 8, short line, kitu atveju long line, kas yra daugiau, nei 8
dukeofyork.txt short line: The grand old Duke of York short line: He had ten thousand men long line: He marched them up to the top of the hill short line: And he marched them down again long line: And when they were up they were up long line: And when they were down they were down short line: And when they were only half-way up short line: They were neither up nor down
Galima tą patį užrašyti ir išsaugoti faile
cat shortlong.awk
{
if ( NF<8 ) {
print "Short line:", $0
} else {
print "Long line:", $0
}
}
Panaudojame su –f
$ awk -f shortlong.awk dukeofyork.txt
Unix shell galima programą paleisti dar keliais būdais. Programą išsaugoti su galūnę sh pvz. shortlong.sh
awk '{
if ( NF<8 ) {
print "Short line:", $0
} else {
print "Long line:", $0
}
}' dukeofyork.txt
Kadangi visą komanda apskliaudėme kabutėmis ir įrašėme failą, mums nebereikia papildomai rašyti failo. Tuomet viską paleidžiame su tokia eilute:
sh shortlong.sh
18. pavyzdys – for ciklo naudojimas
For ciklo naudojimo pavyzdys.
cat firstthree.awk
{
for ( i=1; i<=3; i++ ) {
print "Line " NR ", field " i ": " $i;
}
}
Ciklas sukasi tris kartus, tol kol i tampa lygus 3 . Kiekvieną kartą spausdina atitinkamą lauką (stolpelį).
cat dukeofyork.txt The grand old Duke of York He had ten thousand men He marched them up to the top of the hill And he marched them down again And when they were up they were up And when they were down they were down And when they were only half-way up They were neither up nor down
Kodas: awk -f firstthree.awk dukeofyork.txt
Line 1, field 1: The Line 1, field 2: grand Line 1, field 3: old Line 2, field 1: He Line 2, field 2: had Line 2, field 3: ten Line 3, field 1: He Line 3, field 2: marched Line 3, field 3: them Line 4, field 1: And Line 4, field 2: he Line 4, field 3: marched Line 5, field 1: And Line 5, field 2: when Line 5, field 3: they Line 6, field 1: And Line 6, field 2: when Line 6, field 3: they Line 7, field 1: And Line 7, field 2: when Line 7, field 3: they Line 8, field 1: They Line 8, field 2: were Line 8, field 3: neither
19. pavyzdys – printf naudojimas
Naudosime printf atspausdinti su vienodais ir tvarkingais tarpais. Puslapyje visko korektiškai neatvaizduoja.
%-20s – spausdins $1 dalį -20 reiškia, kad rikiuos pagal kairę pusę ir to lauko minimalus ilgis bus 20 simbolių
%-35s – spausdins $2 dalį -35 reiškia, kad rikiuos pagal kairę pusę ir to lauko minimalus ilgis bus 35 simbolių
%06.2f\n – spausdins $3 dalį 06.2f reiškia, kad viso eilutė turi 6 simbolius, 0, kad rodys būtent nūlį prieš viską. .2 dalis parodo, kas spausdins du skaičius po kablelio, o f raidė nusako, kad bus skaitinė float reikšmė.
Kitos galima printf formatavimo reikšmės:
%[-]m.nx – čia % – formatavimo eilutės pradžios simbolis, x – nurodo formatavimo sekos tipą, jo reikšmės gali būti tokios:
čia % – formatavimo eilutės pradžios simbolis, x – nurodo formatavimo sekos tipą, jo reikšmės gali būti tokios:
- s simbolių eilutė
- c simbolis
- d dešimtainis sveikas skaičius
- x šešioliktainis skaičius
- o aštuntainis skaičius
- e eksponentinė realaus skaičiaus išraiška
- f realus skaičius
- g kompaktinė realaus skaičiaus išraiška
Priklausomai nuo x reikšmės skaičiai m ir n gali būti traktuojami skirtingai. Paprastai m yra minimali o n maksimali lauko reikšmė.
Taip pat gali būti naudojami specialūs simboliai:
- \n perkelia į kitą eilutę
- \t spausdina su tarpais
- \c spausdina toje pačioje eilutėje
awk -F, '{printf("%-20s %-35s %06.2f\n", $1, $2, $3)}' nameemailavg.csv
Art Venere art@venere.org 256.62
Lenna Paprocki lpaprocki@hotmail.com 259.69
Donette Foller donette.foller@cox.net 282.33
Simona Morasca simona@morasca.com 139.52
Dominque Dickerson dominque.dickerson@dickerson.org 167.05
Leota Dilliard leota@hotmail.com 253.65
Sage Wieser sage_wieser@cox.net 155.56
Kris Cho kris@gmail.com 210.79
Minna Amigon minna_amigon@yahoo.com 095.48
Abel Maclead amaclead@gmail.com 225.77
Kiley Caldarera kiley.caldarera@aol.com 172.96
Graciela Ruta gruta@cox.net 202.68
Josephine Darakjy josephine_darakjy@darakjy.org 178.88
Cammy Albares calbares@gmail.com 290.45
Mattie Poquette mattie@aol.com 283.24
Meaghan Garufi meaghan@hotmail.com 227.14
Gladys Rim gladys.rim@rim.org 243.46
Yuki Whobrey yuki_whobrey@aol.com 128.32
Fletcher Flosi fletcher.flosi@yahoo.com 221.39
