
AWK kalba - subtiliau ir daugiau
Kiek anksčiau pristatėme awk kalbą (žr. >>>>> ). Dabar pateiksime naujų aspektų, tačiau prieš tai noriu
paminėti pora įdomybių. Dėl visų susitarimų ir detalesnių paaiškinimų žiūrėkite
įvadiniame puslapyje...
1. Visada smalsu, kokia yra trumpiausia kažką realaus daranti programa. Pabandykime tokią:
# maza.awk labai maža programa
{ }
O dabar pabandykime ją įvykdyti nurodydami kokį nors failą.
awk f maza.awk test.txt
Programa nepateikia jokių rezultatų. Ar ji tikrai kažką daro? Visų pirma ji nuskaito visą nurodytą failą eilutė po
eilutės. Tačiau kokia iš to nauda? Ogi tas, kad šią programą galima panaudoti patikrinimui, ar failas egzistuoja, o taip
pat, jei jis egzistuoja, ar nėra pažeistas. Taigi, ji turi prasmę!
2. Kita įdomus iššūkis parašyti programą, kuri spausdina savo pačios tekstą. awk tai pasiekiama
paprastai programai pateikiamas pačios programos failas, kurio turinį ji atspausdina. Paprasčiausia tokia programa
būtų (pavadinkime ją savipati.awk):
{ print }
Vykdome šią programą nurodydami pačios programos failą ir ji išveda savo pačios tekstą, t.y.
awk f savipati.awk savipati.awk
{ print }
Išraiškos
Išraiškas sudaro operatoriais sujungtos konstantos, kintamieji, funkcijos, reguliariuosius išraiškos.
Konstantos yra simbolių eilutės arba skaitinės reikšmės.
Simbolių eilutės yra į kabutes paimtos simbolių sekos, pvz., "Labas, pasauli!". Eilutėse galima panaudoti ir specialias
konstrukcijas (angl. escape sequences), kurių populiaresnės yra:
\n naujos eilutės kodas (\xa);
\r eilutės pradžios kodas (\xd);
\t tabuliacijos kodas (\x9);
\xhh - simbolis, kurio šešioliktainė reikšmė nurodyta hh, pvz., \x41 reiškia raidę A;
\c bet koks konkretus simbolis c. Dažniausiai naudojamas ypatingiems simboliams nurodyti,
pvz., kabutėms. Pvz., "Sakyk \"Labas!\" "
Kintamasis yra vardas, kuriuo žymima nuoroda į reikšmę. Kintamojo atskiro aprašymo nėra, jo sukūrimui pakanka
priskirti reikšmę. Kintamojo varde galima naudoti tik (lotyniškas) raides, skaitmenis ir pabraukimo simbolį ( _ ) ir jis
negali prasidėti skaitmeniu. Beje, awk kalboje didžiosios ir mažosios raidės laikomos skirtingomis, tad
kintamieji alga ir Alga yra skirtingi. Kintamiesiems nenurodomas jų tipas jis atpažįstamas iš konteksto.
Kintamojo (arba simbolių eilutės), kurio reikšmė nėra skaitmenys, skaitinė reikšmė yra 0.
Pvz., išraiška x = "abc" + 7 kintamajam x priskiria reikšmę 7.
Su objektais (kintamaisiais ir konstantomis) galima atlikti veiksmus. Aritmetiniams veiksmams naudojamo šie
operatoriai:
+ - sudėtis;
- - atimtis
* - daugyba;
/ - dalyba;
% - liekana;
^ (arba ** ) kėlimas laipsniu.
Eilučių sujungimo operatorius yra tarpas, pvz.,
BEGIN { vardas = "Jonai"; kreipinys = "Labas, " vardas "!"; print kreipinys; }
Programa atspausdins
Labas, Jonai!
Priskyrimo operatoriai
Standartinis priskyrimo operatorius yra = , pvz., x=1; ,
tačiau awk leidžia tokius "optimizuotus" (C stiliumi) operatorius:
++ - padidinti vienetu;
-- - sumažinti vienetu;
+= - pridėti;
-+ - atimti;
*= - padauginti;
/= - padalinti;
%= - priskirti liekaną;
^= (arba **= )- pakelti laipsniu.
Įdomu, kad ++ ir -- operatorius galima naudoti
iš kairės ir iš dešinės interpretuojami juos skirtingai. Naudojant iš
dešinės, pirma paimama (ir panaudojama išraiškoje) objekto (pvz., kintamojo) reikšmė, o tik tada objekto reikšmė
pakeičiama (padidinant ar sumažinant vienetu). Naudojant iš kairės, pirma pakeičiama reikšmė, o vėliau ši (jau
pakeista) naudojama išraiškoje.
Pailiustruosime tai pavyzdžiu:
BEGIN { t=3; x=9; print t++, x+t;
t=3; x=9; print --t, (--x)+t;
}
Pirmasis print atspausdins 3 ir 13 - spausdinama ankstesnė t
reikšmė, t reikšmė padidinama vienetu ir ši naujoji (4) reikšmė panaudoja tolimesniuose skaičiavimuose (x+t).
Antrasis print atspausdins 2 ir 10 - sumažinama vienetu t reikšmė,
tada ji atspausdinama, tada vienetu sumažinama x reikšmė, kuri sudedama su t reikšme (jau sumažinta
vienetu anksčiau).
Beje, ++ ir - naudojimui yra apribojimų, pvz., jų negalima panaudoti
su skaičiais ar išraiškomis (klaidingas užrašas
būtų t = 3++; arba x = --(t+5);
Apibendrinant, tarkim, x=x+1; galima užrašyti it kitais skirtingais būdais: <
CODE>x+=1; x++; ++x;
Palyginimo operatoriai:
< - mažiau;
> - daugiau;
<= - mažiau arba lygu;
>= - daugiau arba lygu;
== - lygu;
!= - nelygu;
~ - tenkina šabloną;
!~ - netenkina šablono;
|| - loginis arba;
&& - loginis ir;
! = loginis ne.
Išvedimas
Išvedimas gali būti nukreiptas į failą arba konvejerį, pvz.,
print rezultatas > "failo_vardas.txt"
print rezultatas | "komanda"
Pateiksime pavyzdį, išskiriantį visus žodžius tekste ir paskaičiuojantį jų pasikartojimų skaičių:
BEGIN { FS = "[^a-zA-Z+]"; OFS = ": ";
print "Žodžių pasiskirstymas faile", ARGV[1] > "pasiskirstymas.txt";
}
{ for (i=1; i <= NF; i++) words[tolower($i)]++; }
END { for (i in words) print words[i], i > "pasiskirstymas.txt" }
Šablono paėmimas iš komandos eilutės
# sablonas.awk; pirmas parametras panaudojamas kaip šablonas
BEGIN { sablonas = ARGV[1];
# pastumiami komandos eilutės argumentai, kad šablonas nebūtų failo vardu
ARGC--; for (i=1; i <= ARGC; i++) ARGV[i] = ARGV[i+1];
if (ARGC == 1) { ARGC = 2; ARGV[1] = "-"; }
}
$0 ~ sablonas { print }
Vykdykime programą, nurodydami, kad reikia pateikti tas teksto eilutes, kuriose yra žodis Jonas:
awk f sablonas.awk Jonas test.txt
Pastaba: Būtina ne tik paimti argumentą (šabloną), bet ir užtikrinti, kad awk nebandytų jo panaudoti kaip failo, kurį
reikia skaityti, vardo.
Formatuotas išvedimas
Kadangi viena pagrindinių awk funkcijų yra pateikti rezultatus (pavadinkime tai ataskaitomis), tai labai
svarbu, kad tai galėtume padaryti priimtinu formatu. Todėl greta print yra ir printf
, pasiskolintas iš C kalbos. Pirmiausia, jis gali ir paprasčiausiai išvesti teksto eilutę, kaip tai daro
print , pvz.,
BEGIN { printf ("Labas, pasauli!\n"); }
Pagrindinis skirtumas tas, kad printf automatiškai neprideda naujos eilutės kodo, kuris
identifikuotas kaip \n.
printf sintaksė yra
printf (formatuojanti_išraiška [,argumentai])
Beje, skliaustai nėra būtini, - kaip ir argumentai (kaip jų ir nebuvo ankstesniame pavyzdyje).
Formatuojanti išraišką sudaro tekstas, o taip pat formatų specifikatoriai, kurie įvedami procento ženklu (%).
Pateiksime pagrindinių specifikatorių sąrašą:
%c vienas ASCII simbolis;
%d dešimtainis sveikas skaičius;
%i dešimtainis sveikas skaičius (papildyta POSIX);
%e slankaus kablelio skaičius formatu [-]d.trupmeninė_daliselaipsnis;
%E slankaus kablelio skaičius formatu [-]d.trupmeninė_dalisElaipsnis;
%f slankaus kablelio skaičius formatu [-]ddd. trupmeninė_dalis;
%g - %e arba %f tas variantas, kuris trumpesnis;
%G - %E arba %f tas variantas, kuris trumpesnis;
%o aštuntainė reikšmė be ženklo;
%s eilutė;
%x šešioliktainė reikšmė be ženklo; skaitmenys 10-15 vaizduojami kaip a-f;
%X šešioliktainė reikšmė be ženklo; skaitmenys 10-15 vaizduojami kaip A-F;
%% - ženklas %.
Be to, printf galima nurodyti išvedamos reikšmės ženklų skaičių bei tikslumą (skaitinėms
reikšmėms), o taip pat lygiavimą. Apibendrintas specifikatoriaus formatas būtų
%-plotis.tikslumas specifikatorius , pvz.,
BEGIN { printf "|%10s|\n", "Labas!"; }
nurodo, kad reikia išvesti 10 eilutės ženklų, tad pateikiamas rezultatas bus:
| Labas!|
Bet jei norime pateikiamą tekstą lygiuoti pagal kairę pusę, turime naudoti -, t.y.,
BEGIN { printf "|%-10s|\n", "Labas!"; }
pateiksiantį atsakymą:
|Labas! |
Išsamesniui pavyzdžiui grįškime prie
ankstesniame straipsnelyje pateikto pavyzdžio:
# Suskaičiuoti eilutes, žodžius ir simbolius, esančius įvedimo sraute
function sumuoti (p1, p2) { return p1 + p2 }
BEGIN { nw = 0; ns = 0 }
{ nw += NF; ns = sumuoti(ns, length + 1) }
END { print "Tekste yra", NR, "eilučių,", nw, "žodžių ir", ns, "simbolių" }
>
Jame END { } dalį perrašykime taip:
END { printf ("Tekste yra %d eilučių, %d žodžių ir %d simbolių\n", NR, nw, ns); }
Pabandykite abu variantus ir pastebėkite atsakymų pateikimo skirtumus.
Pastaba: Visi pavyzdžiai buvo išbandyti su GAWK ir
MAWK realizacijomis Windows (32 bitų) terpei (nuorodos - atsisiuntimui).
[ vėliau bus pateikta trečia šios (awk) temos dalis ]
Kelios AWK skirtos knygos:
- A.V. Aho, B.W. Kernighan, P.J. Weinberger. The AWK Programming Language, 1988
- A. Robbins. Effective awk Programming, 3rd ed., 2001
- D. Dougherty, A. Robbins. sed & awk, 2nd ed., 1997
- A. Robbins. Effective Awk Programming: A User's Guide for Gnu Awk, 2000
Ankstesnės "Advanced HTML" skyrelio temos:
Unix komandinės eilutė
AWK kalba - sena ir nuolat aktuali
Dygios JavaScript eilutės
Sveikųjų skaičių žaidimai
Pelė uodega švystelėjo...
Pitonas, kandantis sau uodegą
CGI.pm biblioteka: sausainiai
Ką delne mums neša HTML 4.0?
Kaip valdyti piešinių pakrovimo tvarką
Įvadas į Perl kalbą: Kas naudoja Perl?
Kaip lankytoją nukreipti į kitą WWW puslapį
Įlįskite į lankytojų kailį
Kaip sužinoti ekrano charakteristikas?
Vaizdi rašysena - VB Script
Programavimas Unix aplinkoje
ASP patarimų liūnas
Ruby on Rails
JavaScript atspindžiai
|