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