mawk

Autres langues

Langue: pl

Autres versions - même langue

Version: 22 grudnia 1994 (openSuse - 09/10/07)

Section: 1 (Commandes utilisateur)

NAZWA

mawk - jêzyk wyszukiwania wzorców i przetwarzania tekstu

SK£ADNIA

mawk
[-W opcja] [-F warto¶æ] [-v zmn=warto¶æ]
[--] 'tekst programu' [plik...]
mawk
[-W opcja] [-F warto¶æ] [-v zmn=warto¶æ]
[-f plik-programu] [--] [plik...]

OPIS

mawk jest interpreterem jêzyka programowania AWK. Jêzyk AWK jest u¿yteczny w dzia³aniach na plikach danych, wyszukiwaniu i przetwarzaniu tekstu oraz tworzeniu prototypów i eksperymentowaniu z algorytmami. mawk implementuje jêzyk AWK, jak go zdefiniowali Aho, Kernighan i Weinberger w ksi±¿ce The AWK Programming Language, Addison-Wesley Publishing, 1988 (dalej wzmiankowanej jako ksi±¿ka AWK). mawk jest zgodny z definicj± jêzyka AWK ze standardu Posix 1003.2 (propozycja 11.3), zawieraj±c± nowe cechy nie opisane w ksi±¿ce AWK. Dodatkowo mawk zawiera nieco rozszerzeñ.

Program AWK jest sekwencj± par wzorzec {akcja} i definicji funkcji. Krótkie programy wprowadzane s± w wierszu poleceñ, zwykle ujête w ' ', by unikn±æ interpretacji ich sk³adowych przez pow³okê. D³u¿sze programy mog± byæ czytane z pliku przy pomocy opcji -f. dane wej¶ciowe odczytywane s± z listy plików z wiersza poleceñ lub ze standardowego wej¶cia, gdy lista ta jest pusta. Wej¶cie rozbijane jest na rekordy okre¶lone wed³ug zmiennej opisuj±cej separator rekordów, RS (record separator). Pocz±tkowo RS="\n" a rekordy s± to¿same z wierszami. Ka¿dy z rekordów porównywany jest z ka¿dym ze wzorców, a je¶li pasuje, wykonywany jest tekst programu dla {akcji}.

OPCJE

-F warto¶æ
ustawia separator pól, FS, na warto¶æ.
-f plik
Tekst programu jest czytany z pliku zamiast z wiersza poleceñ. Dopuszcza siê wielokrotne u¿ycie opcji -f.
-v zmn=warto¶æ
przypisuje warto¶æ zmiennej programu zmn.
--
wskazuje jednoznaczny koniec opcji.

Powy¿sze opcje bêd± dostêpne w ka¿dej zgodnej z Posix implementacji AWK. Opcje specyficzne dla danej implementacji poprzedzane s± przez -W. mawk udostêpnia sze¶æ takich rozszerzeñ:

-W version
mawk wypisuje sw± wersjê i prawa autorskie na stdout (standardowym wyj¶ciu), za¶ wkompilowane ograniczenia na stderr (standardowym wyj¶ciu b³êdów). Koñczy pracê z kodem 0.
-W dump
wypisuje na stdout asembleropodobny listing wewnêtrznej reprezentacji programu i koñczy pracê z kodem 0 (przy pomy¶lnej kompilacji).
-W interactive
ustawia niebuforowane zapisy na stdout i buforowane wierszami odczyty z stdin (standardowego wej¶cia). Rekordy z stdin s± wierszami niezale¿nie od warto¶ci RS.
-W exec plik
Tekst programu czytany jest z pliku i jest to ostatnia opcja. Przydatne na systemach obs³uguj±cych konwencjê "liczb magicznych" #! dla skryptów wykonywalnych.
-W sprintf=num
ustawia rozmiar bufora wewnêtrznego sprintf na num bajtów. Czêstsze ni¿ sporadyczne stosowanie tej opcji wskazuje, ¿e mawk powinien zostaæ zrekompilowany.
-W posix_space
wymusza na mawk, by nie uwa¿a³ '\n' za odstêp.

Rozpoznawane s± krótkie postacie -W[vdiesp], za¶ w niektórych systemach -We jest obowi±zkowe dla unikniêcia ograniczeñ d³ugo¶ci wiersza poleceñ.

JÊZYK AWK

1. Struktura programu

Program w jêzyku AWK jest sk³ada siê z sekwencji par wzorzec {akcja} i definicji funkcji u¿ytkownika.

Wzorcem mo¿e byæ:


BEGIN END wyra¿enie wyra¿enie, wyra¿enie


Mo¿na pomin±c jeden z elementów z pary wzorzec {akcja}, ale nie oba. Je¿eli pominiêto {akcjê}, to jest ni± domniemane { print }. Je¿eli pominiêto wzorzec, to jest on niejawnie dopasowany. Wzorce BEGIN i END wymagaj± akcji.

Instrukcje zakoñczone s± znakami nowej linii, ¶rednikami lub oboma tymi znakami. Grupy instrukcji, jak akcje czy cia³a pêtli, ³±czone s± w bloki za po¶rednictwem { ... }, jak w C. Ostatnia instrukcja w bloku nie wymaga znaku koñcz±cego. Puste wiersza nie maj± znaczenia; pusta instrukcja zakoñczona jest ¶rednikiem. D³ugie instrukcje mo¿na kontynuowaæ przy pomocy odwrotnego uko¶nika \. Instrukcjê mo¿na podzieliæ miêdzy wiersze bez u¿ycia odwrotnego uko¶nika po przecinku, nawiasie otwieraj±cym, &&, ||, do, else, nawiasie zamykaj±cym instrukcji if, while lub for oraz nawiasie zamykaj±cym definicji funkcji. Komentarze zaczynaj± siê od # i rozci±gaj± siê do a¿ koñca wiersza, choæ go nie obejmuj±.

Poni¿sze instrukcje steruj± przep³ywem programu wewn±trz bloków.


if ( wyra¿ ) instrukcja
if ( wyra¿ ) instrukcja else instrukcja
while ( wyra¿ ) instrukcja
do instrukcja while ( wyra¿ )
for ( wyr_opc ; wyr_opc ; wyr_opc ) instrukcja
for ( zmn in tablica ) instrukcja
continue
break

2. Typy danych, konwersja i porównywanie

Istniej± dwa podstawowe typy danych, numeryczny i ³añcuch znakowy. Sta³e liczbowe mog± byæ ca³kowite, jak -2, dziesiêtne jak 1.08, lub podane w notacji naukowej jak -1.1e4 czy .28E-3. Wszystkie liczby s± reprezentowane wewnêtrznie w arytmetyce zmiennoprzecinkowej. Wszystkie obliczenia równie¿ s± zmiennoprzecinkowe. Tak wiêc, na przyk³ad, wyra¿enie 0.2e2 == 20 jest prawd±. Prawda reprezentowana jest jako 1.0.

Sta³e ³añcuchowe ujête s± w cudzys³owy.

"To jest ³añcuch ze znakiem nowej linii na koñcu.\n"

£añcuchy znakowe mog± byæ kontynuowane w kolejnych wierszach dziêki poprzedzeniu znaku nowej linii odwrotnym uko¶nikiem (\). Rozpoznawane s± nastêpuj±ce sekwencje specjalne:




    \\        \

    \"        "

    \a        dzwonek, ascii 7

    \b        backspace, ascii 8

    \t        tabulacja, ascii 9

    \n        znak nowej linii, newline , ascii 10

    \v        tabulacja pionowa, ascii 11

    \f        wysuw strony, formfeed, ascii 12

    \r        powrót karetki, carriage return, ascii 13

    \ddd      1, 2 lub 3 cyfry ósemkowe dla ascii ddd

    \xhh      1 lub 2 cyfry szesnastkowe dla ascii hh



Je¿eli odwrotnym uko¶nikiem zostanie poprzedzony inny znak, np. \c, wynikiem bêdzie sekwencja ¼ród³owa: \c, tzn. mawk zignoruje specjalne w³a¶ciwo¶ci odwrotnego uko¶nika.

Naprawdê istniej± trzy podstawowe typy danych; trzecim jest liczba i ³añcuch, posiadaj±cy równocze¶nie warto¶æ liczbow± i warto¶æ ³añcuchow±. Zmienne definiowane przez u¿ytkownika pojawiaj± siê przy pierwszym ich u¿yciu i s± inicjowane na null, typu "liczba i ³añcuch", maj±ce warto¶æ numeryczn± 0 a ³añcuchow± "". Nietrywialne dane typu liczbowo-³añcuchowego pochodz± z wej¶cia i zwykle przechowywane s± w polach (zobacz sekcja 4).

Typ wyra¿enia okre¶lany jest przez jego kontekst. W razie potrzeby wykonywana jest automatyczna konwersja typów. Na przyk³ad, wyznaczenie warto¶ci instrukcji




        y = x + 2  ;  z = x  "hello"



Warto¶æ przechowywana w zmiennej y otrzyma typ numeryczny. Je¿eli x nie jest numeryczne, to warto¶æ odczytana z x zostanie skonwertowana na liczbê przed dodaniem do 2 i zachowaniem w y. Warto¶æ przechowywana w zmiennej z bêdzie typu ³añcuchowego: warto¶æ x zostanie przekszta³cona na ³añcuch, je¶li bêdzie to niezbêdne, i z³±czona z "hello". Oczywi¶cie, warto¶æ i typ przechowywane w x nie zmieniaj± siê w ¿adnej z tych konwersji. Wyra¿enie ³añcuchowe przekszta³cane jest na numeryczne przy zastosowaniu najd³u¿szego swego przedrostka numerycznego jak w atof(3). Wyra¿enie numeryczne konwertowane jest na ³añcuch poprzez zast±pienie wyra¿ przez sprintf(CONVFMT, wyra¿), chyba ¿e wyra¿ mo¿e byæ reprezentowane w danym komputerze jako dok³adna liczba ca³kowita, wówczas przekszta³cane jest na sprintf("%d", wyra¿). Sprintf() jest funkcj± wbudowan± AWK, dubluj±c± dzia³anie sprintf(3), za¶ CONVFMT jest wbudowan± zmienn± u¿ywan± do wewnêtrznej konwersji z liczby na ³añcuch i inicjowan± na "%.6g". Mo¿na wymusiæ jawn± konwersjê typów: wyra¿ "" jest ³añcuchowe, a wyra¿+0 jest numeryczne.

Przy wyliczaniu, wyra¿1 op-rel wyra¿2, je¿eli oba operandy s± numeryczne lub numeryczno-³añcuchowe, to porównywanie jest numeryczne; je¿eli oba operandy s± ³añcuchami to porównywanie jest ³añcuchowe; je¶li jeden z operandów jest ³añcuchem, to operand nie-³añcuchowy jest przekszta³cany i porównywanie jest ³añcuchowe. Wynik jest numeryczny, 1 lub 0.

W kontekstach logicznych, jak if ( wyra¿ ) instrukcja, warto¶ci± wyra¿enia ³añcuchowego jest prawda wtedy i tylko wtedy, gdy nie jest ono ³añcuchem pustym ""; wyra¿eñ liczbowych wtedy i tylko wtedy gdy nie s± numerycznie zerem.

3. Wyra¿enia regularne

W jêzyku AWK rekordy, pola i ³añcuchy s± czêsto sprawdzane na dopasowanie do wyra¿enia regularnego. Wyra¿enia regularne umieszczone s± miêdzy uko¶nikami, a



        wyra¿ ~ /r/



jest wyra¿eniem AWK o warto¶ci 1 je¶li wyra¿ "pasuje do" r, co oznacza, ¿e pewien pod³añcuch wyra¿ jest w zestawie ³añcuchów zdefiniowanych przez r. Je¶li nie wystêpuje dopasowanie, to wyra¿enie otrzymuje warto¶æ 0; zast±pienie ~ operatorem "nie pasuje", !~, odwraca znaczenia. Pary wzorzec-akcja



        /r/ { akcja }   i   $0 ~ /r/ { akcja }



s± takie same, za¶ dla ka¿dego rekordu wej¶ciowego pasuj±cego do r wykonywana jest akcja. Faktycznie, /r/ jest wyra¿eniem AWK równowa¿nym ($0 ~ /r/) wszêdzie z wyj±tkiem wyst±pienia po prawej stronie operatora dopasowania lub przekazywania do funkcji wbudowanej oczekuj±cej jako argumentu wyra¿enia regularnego.

AWK stosuje rozszerzone wyra¿enia regularne jak egrep(1). Metaznakami wyra¿eñ regularnych, tj. znakami o specjalnym znaczeniu w wyra¿eniach regularnych s±




         ^ $ . [ ] | ( ) * + ?



Wyra¿enia regularne konstruowane s± ze znaków jak ni¿ej:
c
dopasowuje dowolny znak nie bêd±cy metaznakiem c.
\c
dopasowuje znak zdefiniowany przez tê sam± sekwencjê specjaln± u¿ywan± w sta³ych ³añcuchowych lub dos³owny znak c je¶li \c nie jest sekwencj± specjaln±.
.
dopasowuje dowolny znak (³±cznie ze znakiem nowej linii).
^
dopasowuje pocz±tek ³añcucha.
$
dopasowuje koniec ³añcucha.
[c1c2c3...]
dopasowuje dowolny znak z klasy c1c2c3... . Zakres znaków oznaczany jest przez c1-c2 wewn±trz klasy [...].
[^c1c2c3...]
dopasowuje dowolny znak nie nale¿±cy do klasy c1c2c3...

Wyra¿enia regularne konstruowane s± z innych wyra¿eñ regularnych w nastêpuj±cy sposób:

r1r2
dopasowuje r1, bezpo¶rednio po którym nastêpuje r2 (konkatenacja).
r1 | r2
dopasowuje r1 lub r2 (alternatywa).
r*
dopasowuje zero lub wiêcej wyst±pieñ r .
r+
dopasowuje jedno lub wiêcej r.
r?
dopasowuje zero lub jedno r.
(r)
dopasowuje r, umo¿liwiaj±c grupowanie.

Operatory wed³ug rosn±cego priorytetu: alternatywa, konkatenacja (z³±czenie) i operatory jednoargumentowe (*, + lub ?).

Na przyk³ad,




    /^[_a-zA-Z][_a-zA-Z0-9]*$/  i

    /^[-+]?([0-9]+\.?|\.[0-9])[0-9]*([eE][-+]?[0-9]+)?$/



dopasowuj± odpowiednio identyfikatory AWK i sta³e liczbowe AWK. Zauwa¿, ¿e kropka . musi byæ chroniona odwrotnym uko¶nikiem, by zosta³a rozpoznana jako kropka dziesiêtna, a nie dopasowanie dowolnego znaku, a metaznaki wewn±trz klas znaków trac± swe specjalne znaczenie.

Po prawej stronie operatorów ~ lub !~ mo¿e zostaæ u¿yte dowolne wyra¿enie. Podobnie, dowolne wyra¿enie mo¿na przekazaæ do funkcji wbudowanej oczekuj±cej wyra¿enia regularnego. W razie potrzeby zostanie ono przekszta³cone na ³añcuch, a nastêpnie zinterpretowane jako wyra¿enie regularne. Na przyk³ad,




        BEGIN { identifier = "[_a-zA-Z][_a-zA-Z0-9]*" }



        $0 ~ "^" identifier



wypisuje wszystkie wiersze zaczynaj±ce siê od jakiego¶ identyfikatora AWK.

mawk rozpoznaje puste wyra¿enie regularne, //, dopasowuj±ce ³añcuch pusty. Zatem pasuje do niego dowolny ³añcuch na pocz±tku, koñcu i pomiêdzy dowolnym znakiem. Na przyk³ad,




        echo  abc | mawk '{ gsub(//, "X") ; print }'

        XaXbXcX



4. Rekordy i pola

Rekordy czytane s± po jednym na raz, i przechowywane w zmiennej $0. Rekord rozbijany jest na pola, przechowywane w $1, $2, ..., $NF. Wbudowana zmienna NF ustawiana jest na liczbê pól, a NR i FNR s± zwiêkszane o 1. Pola powy¿ej $NF ustawiane s± na "".

Przypisanie do $0 powoduje, ¿e pola i NF s± obliczane ponownie. Przypisanie do NF lub do pola powoduje, ¿e $0 jest ponownie tworzone przez z³±czenie kolejnych pól separowanych przez OFS. Przypisanie do pola o indeksie wiêkszym od NF, powiêksza NF i powoduje ponowne utworzenie $0.

Dane wej¶ciowe przechowywane w polach s± ³añcuchami, chyba ¿e ca³e pole ma postaæ numeryczn± a wówczas typ jest liczbowo-³añcuchowy. Na przyk³ad,


        echo 24 24E |

        mawk '{ print($1>100, $1>"100", $2>100, $2>"100") }'

        0 1 1 1

$0 i $2 s± ³añcuchami a $1 jest liczbowo-³añcuchowe. Pierwsze porównanie jest numeryczne, drugie ³añcuchowe, trzecie ³añcuchowe (100 jest konwertowane na "100"), i ostatnie ³añcuchowe.

5. Wyra¿enia i operatory

Sk³adnia wyra¿eñ jest podobna jak w C. Wyra¿eniami pierwotnymi s± sta³e liczbowe, sta³e ³añcuchowe, zmienne, pola, tablice i wywo³ania funkcji. Identyfikator zmiennej, tablicy b±d¼ funkcji mo¿e byæ ci±giem liter, cyfr i znaków podkre¶lenia, nie rozpoczynaj±cym siê od cyfry. Zmienne nie s± deklarowane; zaistniej± przy pierwszym do nich odwo³aniu, a inicjowane s± na null.

Nowe wyra¿enia tworzone s± z u¿yciem poni¿szych, podanych w kolejno¶ci rosn±cego priorytetu, operatorów:


przypisanie                =  +=  -=  *=  /=  %=  ^=

warunkowe                 ?  :

logiczne or               ||

logiczne and              &&

przynale¿no¶æ do tablicy  in

dopasowanie               ~   !~

relacyjne                 <  >   <=  >=  ==  !=

konkatenacja              (bez specjalnego operatora)

dodawanie/odejmowanie     +  -

mno¿enie/dzielenie        *  /  %

jednoargumentowe          +  -

logiczne not              !

potêgowanie               ^

inkrementacja/dekr.       ++ -- (zarówno post jak i pre)

pole                      $

Przypisanie, operatory warunkowe i potêgowanie wi±¿± od prawej do lewej; pozosta³e od lewej do prawej. Ka¿de wyra¿enie mo¿e byæ umieszczone w nawiasach.

6. Tablice

Awk obs³uguje tablice jednowymiarowe. Elementy tablic wskazuje siê jako tablica[wyra¿]. Wyra¿ jest przekszta³cane wewnêtrznie na typ ³añcuchowy, wiêc, na przyk³ad, A[1] i A["1"] s± tym samym elementem, a faktycznym indeksem jest "1". Tablice indeksowane ³añcuchami zwane s± tablicami asocjacyjnymi (tablicami przyporz±dkowuj±cymi). Pierwotnie tablica jest pusta; elementy zaistniej± przy pierwszym do nich odwo³aniu. Wyra¿enie wyra¿ in tablica daje w wyniku 1 je¿eli istnieje tablica[wyra¿], w przeciwnym razie 0.

Istnieje postaæ instrukcji for wykonuj±ca pêtlê po wszystkich indeksach tablicy.




        for ( zmn in tablica ) instrukcja



ustawia zmn na ka¿dy z indeksów tablicy i wykonuje instrukcjê. Kolejno¶æ, w jakiej zmn przechodzi przez indeksy tablicy nie jest zdefiniowana.

Instrukcja delete tablica[wyra¿], powoduje usuniêcie tablica[wyra¿]. mawk obs³uguje rozszerzenie, delete tablica, które usuwa wszystkie elementy tablicy.

Tablice wielowymiarowe tworzone s± sztucznie przez konkatenacjê z zastosowaniem wbudowanej zmiennej SUBSEP. tablica[wyra¿1,wyra¿2] jest równowa¿nikiem tablica[wyra¿1 SUBSEP wyra¿2]. Sprawdzanie elementu tablicy wielowymiarowej u¿ywa indeksu w nawiasach, jak w


        if ( (i, j) in A )  print A[i, j]

7. Zmienne wbudowane

Poni¿sze zmienne s± zmiennymi wbudowanymi. S± one inicjowane przed wykonaniem programu.

ARGC
liczba argumentów wiersza poleceñ.
ARGV
tablica argumentów wiersza poleceñ, 0..ARGC-1.
CONVFMT
format do wewnêtrznej konwersji liczb na ³añcuchy, pocz±tkowo = "%.6g".
ENVIRON
tablica zaindeksowana zmiennymi ¶rodowiska. £añcuch ¶rodowiska, zmn=warto¶æ przechowywany jest jako ENVIRON[zmn] = warto¶æ.
FILENAME
nazwa bie¿±cego pliku wej¶ciowego.
FNR
numer bie¿±cego rekordu w FILENAME.
FS
dzieli rekordy na pola jako wyra¿enie regularne.
NF
liczba pól bie¿±cego rekordu.
NR
numer bie¿±cego rekordu w ca³kowitym strumieniu wej¶ciowym.
OFMT
format do wydruku liczb; pocz±tkowo = "%.6g".
OFS
wstawiane pomiêdzy polami w wyj¶ciu, pocz±tkowo = " ".
ORS
koñczy ka¿dy z rekordów wyj¶ciowych, pocz±tkowo = "\n".
RLENGTH
d³ugo¶æ ustawiona przez ostatnie wywo³anie wbudowanej funkcji match().
RS
separator rekordów wej¶ciowych, pocz±tkowo = "\n".
RSTART
indeks ustawiony przez ostatnie wywo³anie match().
SUBSEP
u¿ywany do budowy indeksów tablic wielowymiarowych, pocz±tkowo = "\034".

8. Funkcje wbudowane

Funkcje ³añcuchowe
gsub(r,s,t) gsub(r,s)
Zastêpowanie globalne (global substitution), ka¿de dopasowanie wyra¿enia regularnego r w zmiennej t zastêpowane jest ³añcuchem s. Zwracana jest liczba wykonanych zast±pieñ. Je¿eli pominiêto t, to u¿ywane jest $0. Znak & w ³añcuchu zastêpuj±cym s zastêpowany jest dopasowanym pod³añcuchem ³añcucha t. \& oraz \\ daj±, odpowiednio, dos³owne & i \ w ³añcuchu zastêpuj±cym.
index(s,t)
Je¿eli t jest pod³añcuchem s, to zwracana jest pozycja, na której rozpoczyna siê t, w przeciwnym razie zwracane jest 0. Pierwszy znak s jest na pozycji 1.
length(s)
Zwraca d³ugo¶æ ³añcucha s.
match(s,r)
Zwraca indeks pierwszego najd³u¿szego dopasowania wyra¿enia regularnego r w ³añcuchu s. Zwraca 0 je¶li nie wystêpuje dopasowanie. Jako skutek uboczny, nastêpuje ustawienie RSTART na zwracan± warto¶æ. RLENGTH ustawiane jest na d³ugo¶æ dopasowania lub -1 je¶li brak dopasowania. Je¿eli dopasowano ³añcuch pusty, to RLENGTH ustawiane jest na 0, a zwracane jest 1 je¶li dopasowanie by³o na pocz±tku, za¶ length(s)+1, gdy na koñcu ³añcucha.
split(s,A,r) split(s,A)
£añcuch s rozbijany jest na pola przez wyra¿enie regularne r a pola wpisywane s± do tablicy A. Zwracana jest liczba pól. Szczegó³y w sekcji 11 poni¿ej. Je¿eli pominiêto r, u¿ywane jest FS.
sprintf(format,lista-wyra¿)
Zwraca ³añcuch utworzony z listy-wyra¿eñ zgodnie z formatem. Zobacz opis printf() poni¿ej.
sub(r,s,t) sub(r,s)
Pojedyncze zast±pienie. Takie samo, jak gsub(), z wyj±tkiem tego, ¿e wykonywane jest co najwy¿ej jedno zast±pienie.
substr(s,i,n) substr(s,i)
Zwraca pod³añcuch ³añcucha s, poczynaj±c od indeksu i, o d³ugo¶ci n. Je¶li pominiêto n, zwracana jest koñcówka s, poczynaj±c od pozycji i.
tolower(s)
Zwraca kopiê s ze wszystkimi du¿ymi literami przekszta³conymi na ma³e.
toupper(s)
Zwraca kopiê s ze wszystkimi ma³ymi literami przekszta³conymi na du¿e.

Funkcje arytmetyczne



atan2(y,x)     arcus tangens z y/x pomiêdzy -PI i PI.



cos(x)         funkcja cosinus, x w radianach.



exp(x)         funkcja wyk³adnicza.



int(x)         zwraca x obciête w stronê zera.



log(x)         logarytm naturalny.



rand()         zwraca liczbê losow± miêdzy zero a jeden.



sin(x)         funkcja sinus, x w radianach.

sqrt(x) zwraca pierwiastek kwadratowy z x.
srand(wyra¿) srand()
Inicjuje ziarenko generatora liczb losowych, u¿ywaj±c zegara je¶li pominiêto wyra¿, i zwraca warto¶æ poprzedniego ziarenka losowego. mawk inicjuje generator liczb losowych wed³ug zegara przy uruchomieniu, wiêc nie ma faktycznej potrzeby wywo³ywania srand(). Srand(wyra¿) przydaje siê do powtarzania ci±gów pseudolosowych.


9. Wej¶cie i wyj¶cie

Istniej± dwie instrukcje wyj¶cia: print i printf.
print
zapisuje na standardowe wyj¶cie $0 ORS.
print wyra¿1, wyra¿2, ..., wyra¿n
zapisuje na standardowe wyj¶cie wyra¿1 OFS wyra¿2 OFS ... wyra¿n ORS. Wyra¿enia numeryczne s± konwertowane na ³añcuchy zgodnie z OFMT.
printf format, lista-wyra¿
powiela funkcjê biblioteczn± printf z C, pisz±c na standardowe wyj¶cie. Rozpoznawany jest komplet specyfikacji formatów z ANSI C z konwersjami %c, %d, %e, %E, %f, %g, %G, %i, %o, %s, %u, %x, %X i %%, oraz kwalifikatorami konwersji h i l.

Lista argumentów print lub printf mo¿e byæ opcjonalnie ujêta w nawiasy. Print formatuje liczby przy pomocy OFMT lub "%d" dla dok³adnie ca³kowitych. "%c" z argumentem numerycznym wypisuje odpowiedni znak 8-bitowy, z argumentem ³añcuchowym wypisuje pierwszy znak ³añcucha. Wyj¶cie print i printf mo¿na przekierowaæ do pliku lub polecenia do³±czaj±c > plik, >> plik lub | polecenie na koñcu instrukcji drukowania. Przekierowanie otwiera plik lub polecenie tylko raz, kolejne przekierowania do³±czane s± do ju¿ otwartego strumienia. Zgodnie z konwencj±, mawk ³±czy nazwê pliku "/dev/stderr" z stderr, co pozwala na przekierowanie wyników print i printf na standardowe wyj¶cie diagnostyczne. mawk wi±¿e równie¿, odpowiednio, "-" i "/dev/stdout" z stdin i stdout, co umo¿liwia przysy³anie tych strumieni do funkcji.

Funkcja wej¶cia getline ma nastêpuj±ce warianty:

getline
czyta do $0, aktualizuje pola, NF, NR i FNR.
getline < plik
czyta do $0 z pliku, aktualizuje pola i NF.
getline zmn
czyta nastêpny rekord do zmiennej zmn, aktualizuje NR i FNR.
getline zmn < plik
czyta nastêpny rekord pliku do zmiennej zmn.
polecenie | getline
przesy³a potokiem rekord z polecenia do $0 i aktualizuje pola i NF.
polecenie | getline zmn
przesy³a potokiem rekord z polecenia do zmiennej zmn.

Getline zwraca 0 na koñcu pliku, -1 przy b³êdzie, w pozosta³ych przypadkach 1.

Polecenia na koñcu potoków wykonywane s± przez /bin/sh.

Funkcja close(wyra¿) zamyka plik lub potok skojarzony z wyra¿. Close zwraca 0 je¿eli wyra¿ jest otwartym plikiem, kod zakoñczenia je¶li wyra¿ jest poleceniem potoku, a -1 w pozosta³ych przypadkach. Close stosowane jest do ponownego odczytu pliku lub polecenia, upewnienia siê, ¿e drugi koniec potoku wyj¶ciowego jest zakoñczony lub do zachowania zasobów plikowych.

Funkcja fflush(wyra¿) wymiata plik wyj¶ciowy lub potok skojarzony z wyra¿. Fflush zwraca 0 je¶li wyra¿ jest otwartym strumieniem wyj¶ciowym, w przeciwnym razie -1. Fflush bez argumentu opró¿nia stdout. Fflush z pustym argumentem ("") opró¿nia wszystkie otwarte wyj¶cia.

Funkcja system(wyra¿) wykorzystuje /bin/sh do wykonania wyra¿ i zwraca kod zakoñczenia polecenia wyra¿. Zmiany tablicy ENVIRON nie s± przekazywane poleceniom wykonywanym przez system lub potoki.

10. Funkcje definiowane przez u¿ytkownika

Funkcja definiowana przez u¿ytkownika ma nastêpuj±c± sk³adniê:



    function nazwa( argumenty ) { instrukcje }



Cia³o funkcji mo¿e zawieraæ instrukcjê zwrócenia warto¶ci (return)



     return opcjonalne-wyra¿



Instrukcja return nie jest wymagana. Wywo³ania funkcji mog± byæ zagnie¿d¿ane lub rekurencyjne. Wyra¿enia przekazywane s± funkcjom przez warto¶æ a tablice przez wskazanie. Dodatkowe argumenty s³u¿± jako zmienne lokalne i s± inicjowane na null. Na przyk³ad, csplit(s,A) wstawia ka¿dy znak s do tablicy A i zwraca d³ugo¶æ s.



        function csplit(s, A,   n, i)

        {

          n = length(s)

          for( i = 1 ; i <= n ; i++ ) A[i] = substr(s, i, 1)

          return n

        }



Wstawienie dodatkowych odstêpów pomiêdzy przekazywanymi parametrami a zmiennymi lokalnymi wynika z konwencji. Do funkcji mo¿na odwo³ywaæ siê przed ich zdefiniowaniem, ale nazwa funkcji i nawias '(' rozpoczynaj±cy listê argumentów musz± siê stykaæ, by unikn±æ pomy³ki z konkatenacj±.

11. Podzia³ ³añcuchów, rekordów i plików

Programy awk u¿ywaj± tego samego algorytmu do rozbicia ³añcuchów na tablice przy pomocy split() i rekordów na pola wed³ug FS. mawk stosuje zasadniczo ten sam algorytm przy podziale plików na rekordy wed³ug RS.

Split(wyra¿,A,sep) dzia³a nastêpuj±co:

(1)
Je¿eli pominiêto sep, to jest on zastêpowany przez FS. Sep mo¿e byæ wyra¿eniem lub wyra¿eniem regularnym. Je¿eli jest wyra¿eniem typu nie-³añcuchowego, to jest przekszta³cane na ³añcuch.
(2)
Je¶li sep = " " (pojedyncza spacja), to <ODSTÊP> jest obcinana z pocz±tku i koñca wyra¿, a sep staje siê <ODSTÊPEM>. mawk definiuje <ODSTÊP> jako wyra¿enie regularne /[ \t\n]+/. W przeciwnym wypadku sep traktowany jest jako wyra¿enie regularne, z wyj±tkiem tego, ¿e metaznaki dla ³añcucha o d³ugo¶ci 1 s± ignorowane, np. split(x, A, "*") i split(x, A, /\*/) s± tym samym.
(3)
Je¿eli wyra¿ nie jest ³añcuchem, jest przekszta³cane na ³añcuch. Je¿eli wyra¿ jest wówczas ³añcuchem pustym "", to split() zwraca 0 a A jest ustawiane jako puste. W przeciwnym razie, wszystkie nienak³adaj±ce siê, niepuste i najd³u¿sze dopasowania sep w wyra¿, dziel± wyra¿ na pola, które wpisywane s± do A. Pola s± umieszczane w A[1], A[2], ..., A[n] a split() zwraca n, liczbê pól, równ± liczbie dopasowañ plus jeden. Dane umieszczone w A wygl±daj±ce na numeryczne otrzymuj± typ liczbowo-³añcuchowy.

Podzia³ rekordów na pola dzia³a tak samo, z wyj±tkiem tego, i¿ czê¶ci wpisywane s± do $1, $2,..., $NF. Je¿eli $0 jest puste, NF jest ustawiane na 0 a wszystkie $i na "".

mawk dzieli pliki na rekordy przy pomocy tego samego algorytmu, ale z t± niewielk± ró¿nic±, i¿ RS jest faktycznie ci±giem koñcz±cym a nie separatorem. (ORS te¿ jest faktycznie ci±giem koñcz±cym).


Np., je¿eli FS = ":+" a $0 = "a::b:" , to NF = 3 a $1 = "a", $2 = "b" i $3 = "", ale je¿eli zawarto¶ci± pliku wej¶ciowego jest "a::b:", za¶ RS = ":+", to istniej± dwa rekordy "a" i "b".

RS = " " nie ma specjalnego znaczenia.

Je¿eli FS = "", to mawk rozbija rekord na pojedyncze znaki, i, podobnie split(s,A,) umieszcza poszczególne znaki s w A.

12. Rekordy wielowierszowe

Poniewa¿ mawk interpretuje RS jako wyra¿enie regularne, obs³uga rekordów wielowierszowych jest ³atwa. Ustawienie RS = "\n\n+", powoduje, ¿e rekordy rozdzielane s± co najmniej jednym pustym wierszem. Je¿eli FS = " " (domy¶lnie), to pojedyncze znaki nowej linii, wed³ug zasad <ODSTÊPU> powy¿ej, staj± siê odstêpami a pojedyncze znaki nowej linii s± separatorami pól.

Na przyk³ad, je¶li w pliku jest "a b\nc\n\n", RS = "\n\n+" a FS = " ", to mamy jeden rekord "a b\nc" z trzema polami "a", "b" i "c". Zmiana FS = "\n", daje dwa pola "a b" i "c"; zmieniaj±c FS = "", otrzymujemy jedno pole identyczne jak rekord.

Traktowanie wierszy ze spacjami lub tabulacjami jako pustych mo¿na uzyskaæ ustawiaj±c RS = "\n([ \t]*\n)+". W celu utrzymania zgodno¶ci z innymi implementacjami awk, ustawienie RS = "" daje te same wyniki, co usuniêcie pustych wierszy z pocz±tku i koñca pliku i okre¶lanie rekordów tak, jakby RS = "\n\n+". Posix wymaga, by "\n" zawsze separowa³o rekordy gdy RS = "" niezale¿nie od warto¶ci FS. mawk nie obs³uguje tej konwencji, gdy¿ zdefiniowanie "\n" jako <ODSTÊPU> czyni j± zbêdn±.

W wiêkszo¶ci przypadków zmieniaj±c RS w celu obs³ugi rekordów wielowierszowych, stosuje siê te¿ zmienione na "\n\n" ORS, aby na wyj¶ciu zachowaæ odstêpy miêdzy rekordami.

13. Wykonywanie programu

Ta sekcja opisuje kolejno¶æ wykonywania programu. Po pierwsze, ARGC ustawiane jest na ca³kowit± liczbê argumentów wiersza poleceñ przekazanych do fazy wykonania programu. ARGV[0] ustawiane jest na nazwê interpretera AWK a ARGV[1] ... ARGV[ARGC-1] przechowuje pozosta³e argumenty wiersza poleceñ z wyj±tkiem opcji i ¼ród³a programu. Na przyk³ad, dla



        mawk  -f  prog  v=1  A  t=hello  B



ARGC = 5 oraz ARGV[0] = "mawk", ARGV[1] = "v=1", ARGV[2] = "A", ARGV[3] = "t=hello" i ARGV[4] = "B".

Nastêpnie wykonywany jest kolejno ka¿dy z bloków BEGIN. Je¿eli program sk³ada siê wy³±cznie z bloków BEGIN, to na tym wykonywanie siê koñczy, w przeciwnym razie otwierany jest strumieñ wej¶ciowy i wykonywanie jest kontynuowane. Je¿eli ARGC równa siê 1, strumieñ wej¶ciowy ustawiany jest na stdin, w przypadku przeciwnym w poszukiwaniu argumentu plikowego sprawdzane s± argumenty wiersza poleceñ ARGV[1] ... ARGV[ARGC-1].

Argumenty wiersza poleceñ dziel± siê na trzy grupy: argumenty plikowe, argumenty przypisañ i ³añcuchy puste "". Przypisanie ma postaæ zmn=³añcuch. Podczas sprawdzania ARGV[i] jako mo¿liwego argumentu plikowego, je¶li jest ono puste to jest pomijane; je¶li jest argumentem typu przypisania, odbywa siê przypisanie warto¶ci zmiennej zmn a i zmienia siê na nastêpny argument; w pozosta³ych przypadkach ARGV[i] jest otwierane jako wej¶cie. Je¿eli otwarcie nie powiedzie siê, wykonywanie programu jest koñczone z kodem 2. Je¿eli ¿aden z argumentów wiersza poleceñ nie jest argumentem plikowym, to wej¶cie pochodzi z stdin. Getline w akcji BEGIN otwiera wej¶cie. "-" jako argument plikowy oznacza stdin.

Po otwarciu strumienia wej¶ciowego ka¿dy z rekordów wej¶cia sprawdzany jest z ka¿dym ze wzorców, a je¶li pasuje, to wykonywana jest akcja skojarzona z danym wzorcem. Wzorzec w postaci wyra¿enia pasuje je¶li jego warto¶ci± logiczn± jest prawda (zobacz koniec sekcji 2). Wzorzec BEGIN zestawiany jest przed rozpoczêciem odczytu wej¶cia, za¶ wzorzec END po przeczytaniu ca³ego wej¶cia. Wzorzec zakresu, wyra¿1,wyra¿2, dopasowuje ka¿dy rekord pomiêdzy rekordem pasuj±cym do wyra¿1 a rekordem pasuj±cym do wyra¿2 ³±cznie z nimi.

Po napotkaniu koñca pliku w strumieniu wej¶ciowym, sprawdzane s± pozosta³e argumenty wiersza poleceñ w poszukiwaniu kolejnego argumentu plikowego. Je¶li taki istnieje, to jest otwierany, w przeciwnym wypadku przyjmuje siê, ¿e zosta³ dopasowany wzorzec END i wykonywane s± wszystkie akcje END.

W rozwa¿anym przyk³adzie, przypisanie v=1 ma miejsce po wykonaniu akcji BEGIN, a dana umieszczona w v otrzymuje typ liczbowo-³añcuchowy. Nastêpnie z pliku A jest czytane wej¶cie. Po koñcu pliku A, zmienna t jest ustawiana na ³añcuch "hello", a B jest otwierany jako wej¶cie. Po osi±gniêciu koñca pliku B s± wykonywane akcje wzorca END.

Przebieg programu na poziomie wzorzec {akcja} mo¿na zmieniæ przy pomocy instrukcji




     next

     exit  wyra¿-opcjonalne.



Instrukcja next powoduje, ¿e odczyt nastêpnego rekordu wej¶ciowego i ponowne sprawdzanie wzorców, od pierwszej pary wzorzec {akcja} programu. Polecenie exit powoduje natychmiastowe wykonanie akcji END lub zakoñczenie programu, je¶li nie ma takich akcji lub je¿eli exit wyst±pi³o w akcji END. wyra¿-opcjonalne ustawia warto¶æ kodu zakoñczenia programu, chyba ¿e zostanie ona przes³oniêta przez pó¼niejszy exit lub ujawniony potem b³±d.

PRZYK£ADY


1. emulacja cat.



     { print }



2. emulacja wc.



     { chars += length($0) + 1  # dodaje jeden dla \n

       words += NF

     }



     END{ print NR, words, chars }



3. zliczanie niepowtarzaj±cych siê "faktycznych s³ów".



     BEGIN { FS = "[^A-Za-z]+" }



     { for(i = 1 ; i <= NF ; i++)  word[$i] = "" }



     END { delete word[""]

           for ( i in word )  cnt++

           print cnt

     }



4. sumowanie drugiego pola ka¿dego rekordu w oparciu o pierwsze pole.



     $1 ~ /credit|gain/ { sum += $2 }

     $1 ~ /debit|loss/  { sum -= $2 }



     END { print sum }



5. sortowanie pliku, porównywanie ³añcuchowe



     { line[NR] = $0 "" }  # wymusza typ porównywania: gdyby

                           # jakie¶ wiersze wygl±da³y

                           # na numeryczne



     END {  isort(line, NR)

       for(i = 1 ; i <= NR ; i++) print line[i]

     }



     #sortowanie A[1..n] metod± wstawiania

     function isort( A, n,   i, j, hold)

     {

       for( i = 2 ; i <= n ; i++)

       {

         hold = A[j = i]

         while ( A[j-1] > hold )

         { j-- ; A[j+1] = A[j] }

         A[j] = hold

       }

       # w razie potrzeby bêdzie utworzony wartownik A[0] = ""

     }



KWESTIE ZGODNO¦CI

Posix-owa 1003.2 (propozycja 11.3) definicja jêzyka AWK jest AWK opisanym w ksi±¿ce AWK z kilkoma rozszerzeniami, jakie pojawi³y siê w nawk z SystemVR4. Rozszerzeniami tymi s±:
Nowe funkcje: toupper() i tolower().
Nowe zmienne: ENVIRON[] i CONVFMT.
Specyfikacje konwersji w printf() i sprintf() wziête z ANSI C.
Nowe opcje polecenia: -v zmn=warto¶æ, wielokrotne opcje -f i opcje charakterystyczne dla implementacji jako argumenty -W.

Posix-owy AWK przetwarza pojedyncze wiersze plików. RS mo¿na zmieniæ z "\n" na inny pojedynczy znak, ale trudno jest znale¼æ jakie¶ tego zastosowanie --- w ksi±¿ce AWK brak odpowiednich przyk³adów. Zgodnie z konwencj±, RS = "", powoduje, ¿e jeden lub wiêcej pustych wierszy rozdziela rekordy, umo¿liwiaj±c obs³ugê rekordów wielowierszowych. Gdy RS = "", "\n" jest zawsze separatorem pól, niezale¿nie od warto¶ci FS.

mawk, z kolei, pozwala by RS by³o wyra¿eniem regularnym. Pojawiaj±ce siê w rekordach "\n" jest traktowane jak odstêp, a FS zawsze okre¶la pola.

Pozbycie siê paradygmatu operowania pojedynczym wierszem mo¿e upro¶ciæ niektóre programy i czêsto poprawiæ wydajno¶æ. Na przyk³ad, zmienieniony przyk³ad 3 (zobacz powy¿ej),




        BEGIN { RS = "[^A-Za-z]+" }



        { word[ $0 ] = "" }



        END { delete  word[ "" ]

          for( i in word )  cnt++

          print cnt

        }



zlicza ilo¶æ niepowtarzaj±cych siê s³ów przez traktowanie ka¿dego s³owa jako rekordu. Przy plikach ¶rednich rozmiarów mawk wykonuje go dwukrotnie szybciej, dziêki uproszczonej pêtli wewnêtrznej.

Poni¿szy program zastêpuje ka¿dy z komentarzy w pliku programu C pojedyncz± spacj±,




        BEGIN {

          RS = "/\*([^*]|\*+[^/*])*\*+/"

                # komentarz jest separatorem rekordów

          ORS = " "

          getline  hold

       }



       { print hold ; hold = $0 }



       END { printf "%s" , hold }



Buforowanie rekordu jest niezbêdne, by unikn±æ zakoñczenia ostatniego z rekordów spacj±.

W mawk poni¿sze wyra¿enia s± równowa¿ne,




        x ~ /a\+b/    x ~ "a\+b"     x ~ "a\\+b"



Powy¿sze ³añcuchy bêd± analizowane dwukrotnie: raz jako ³añcuch i raz jako wyra¿enie regularne. Przy analizie ³añcucha mawk ignoruje stosowanie cytowania odwrotnym uko¶nikiem do znaków nie bêd±cych znakami specjalnymi, zatem \c interpretuje jako \c. Natomiast ksi±¿ka AWK przychyla siê do tego, by \c by³o rozpoznawane jako c, co wymaga podwojonego cytowania metaznaków w ³añcuchach. Posix wprost odmawia zdefiniowania po¿±danego zachowania, przez co po¶rednio wymusza na programach musz±cych dzia³aæ z ró¿nymi wersjami awk stosowanie bardziej przeno¶nego, lecz mniej czytelnego, cytowania z u¿yciem podwójnych odwrotnych uko¶ników.

Posix-owy AWK nie rozpoznaje "/dev/std{out,err}" ani sekwencji specjalnej \x hex w ³añcuchach. W przeciwieñstwie do ANSI C, mawk ogranicza liczbê cyfr, jakie mog± wystêpowaæ po \x do dwóch, gdy¿ obecna implementacja obs³uguje tylko znaki 8-bitowe. Wbudowane fflush pojawi³o siê po raz pierwszy w ostatnim (1993) awk AT&T wydanym dla netlib, i nie jest czê¶ci± standardu Posix. Ca³o¶ciowe usuwanie tablicy przez delete tablica nie jest czê¶ci± standardu Posix.

Posix jawnie zostawia niezdefiniowane zachowanie siê FS = "" i wspomina o podziale rekordów na znaki jako mo¿liwej interpretacji, ale obecnie takie zastosowanie nie jest przeno¶ne miêdzy implementacjami.

Na koniec, sposób w jaki mawk obs³uguje przypadki wyj±tkowe nie opisane w ksi±¿ce AWK ani w propozycji Posix. Niebezpiecznie jest zak³adanie spójno¶ci pomiêdzy implementacjami awk, a bezpiecznie przej¶æ do nastêpnej sekcji.

substr(s, i, n) zwraca znaki ³añcucha s o pozycjach z czê¶ci wspólnej przedzia³u zamkniêtego [1, length(s)] i pó³otwartego [i, i+n). Gdy czê¶æ wspólna jest pusta, zwracany jest ³añcuch pusty; zatem substr("ABC", 1, 0) = "" a substr("ABC", -4, 6) = "A".
Ka¿dy ³añcuch, nawet pusty, pasuje pocz±tkiem do ³añcucha pustego, wiêc s ~ // i s ~ "", s± zawsze równe 1, tak jak match(s, //) i match(s, ""). Ostanie dwa ustawiaj± RLENGTH na 0.
index(s, t) jest zawsze tym samym, co match(s, t1), gdzie t1, to to samo, co t z cytowanymi metaznakami. St±d spójno¶æ z match wymaga, by index(s, "") zawsze zwraca³o 1. Równie¿ warunek: index(s,t) != 0 wtedy i tylko wtedy, gdy t jest pod³añcuchem ³añcucha s, wymusza by index("","") = 1.
Je¿eli getline napotka koniec pliku, getline zmn pozostawia zmienn± zmn bez zmian. Podobnie, w momencie rozpoczêcia akcji END, warto¶ci $0, pól i NF pozostaj± niezmienione od ostatniego rekordu.

ZOBACZ TAK¯E

egrep(1)

Aho, Kernighan and Weinberger, The AWK Programming Language, Addison-Wesley Publishing, 1988, (ksi±¿ka AWK), definiuje jêzyk, rozpoczynaj±c siê samouczkiem a dochodz±c do wielu interesuj±cych programów i wchodz±c g³êboko w kwestie projektowania i analizy programów istotne przy programowaniu w ka¿dym jêzyku.

The GAWK Manual, The Free Software Foundation, 1991, stanowi podrêcznik i opis jêzyka nie usi³uj±cy siêgn±æ g³êbi ksi±¿ki AWK. Zak³ada, ¿e czytelnik mo¿e byæ pocz±tkuj±cym programist±. Sekcja po¶wiêcona tablicom w AWK jest doskona³a. Omawia tak¿e wymagania stawiane AWK przez Posix.

B£ÊDY

mawk nie obs³uguje znaku ascii NUL \0 w plikach ¼ród³owych czy plikach danych. Mo¿na wypisaæ NUL przy pomocy printf z %c, a w wej¶ciu s± dopuszczalne wszystkie inne znaki 8-bitowe.

mawk implementuje printf() i sprintf() przy pomocy funkcji bibliotecznych C, printf i sprintf, wiêc pe³na zgodno¶æ z ANSI wymaga biblioteki ANSI C. W praktyce oznacza to, ¿e kwalifikator konwersji h mo¿e nie byæ dostêpny. mawk przejmuje te¿ wszystkie b³êdy czy ograniczenia tych funkcji.

Twórcy implementacji jêzyka AWK ukazali zgodny brak wyobra¼ni w nazywaniu swych programów.

AUTOR

Mike Brennan (brennan@whidbey.com).