Provided by: manpages-pl_0.6-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

        Uwaga! To tłumaczenie może być nieaktualne!

       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).

INFORMACJE O TŁUMACZENIU

       Powyższe tłumaczenie pochodzi z nieistniejącego już Projektu Tłumaczenia  Manuali  i  może
       nie  być  aktualne.  W  razie  zauważenia  różnic  między  powyższym opisem a rzeczywistym
       zachowaniem opisywanego programu lub  funkcji,  prosimy  o  zapoznanie  się  z  oryginalną
       (angielską) wersją strony podręcznika za pomocą polecenia:

              man --locale=C 1 mawk

       Prosimy  o  pomoc  w  aktualizacji stron man - więcej informacji można znaleźć pod adresem
       http://sourceforge.net/projects/manpages-pl/.