Provided by: manpages-pl_20060617-2_all bug

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  wzorcw, 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
              wyraenie
              wyraenie, wyraenie

       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
       acuch,  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,  wyra1  op-rel  wyra2,  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 wyraenia 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              &&
              przynaleno do tablicy  in
              dopasowanie               ~   !~
              relacyjne                 <  >   <=  >=  ==  !=
              konkatenacja              (bez specjalnego operatora)
              dodawanie/odejmowanie     +  -
              mnoenie/dzielenie        *  /  %
              jednoargumentowe          +  -
              logiczne not              !
              potgowanie               ^
              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[wyra1,wyra2]  jest
       równoważnikiem  tablica[wyra1  SUBSEP  wyra2].   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-wyrae  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 wyra1, wyra2, ..., wyran
                     zapisuje na standardowe wyjście wyra1 OFS wyra2 OFS ...
                     wyran 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=acuch.   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 wzorcw, 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,  wyra1,wyra2,
       dopasowuje  każdy  rekord  pomiędzy  rekordem  pasującym  do  wyra1  a
       rekordem pasującym do wyra2 łą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).