TI:WTBD/Awk

Z Brain-wiki

Awk, skrócony opis

Program awk jest interpreterem prostego języka programowania, wyspecjalizowanego w kierunku dokonywania najrozmaitszych przekształceń na plikach danych, szczególnie zapisanych w postaci tekstowej. Instrukcje języka awk definiujące reguły operacji na danych mogą być zapisane w pliku (skrypcie), lub (w szczególnie prostych przypadkach) podane wprost na linii poleceń.

Istnieje szereg odmian awk-a, które na różne sposoby wzbogacają podstawową specyfikację języka zdefiniowaną w normie POSIX (gawk == GNU awk, mawk, nawk, ...). Pozostaniemy tu na poziomie ich części wspólnej. Warto jednak wiedzieć, że interpreter GNU awk jest swobodnie dostępny w postaci źródłowej (jako program w języku C) -- podobnie jak inne narzędzia z rodziny GNU, i jest programem przenośnym. Ponadto dołączony jest do niego bardzo dobry podręcznik użytkowania (w formacie texinfo), mogący doskonale służyć do nauki programowania w języku awk niezależnie od wykorzystywanej wersji interpretera. ([1])

Awk w zarysie

  • Program w języku Awk składa się z ciągu instrukcji o postaci wzorzec { akcja } oraz (ewentualnie) definicji funkcji.
  • Interpreter awk czyta sekwencyjnie pliki (lub strumień) wejściowy, traktując dane wejściowe jako ciąg rekordów, z których każdy składa się z pewnej liczby pól.
  • Każdy przeczytany rekord danych jest kolejno dopasowywany do podanych w programie wzorców; w przypadku stwierdzenia zgodności z wzorcem, wykonywana jest podana po tym wzorcu akcja, w przeciwnym wypadku akcja ta zostaje pominięta.
  • Akcją domyślną jest wypisanie zawartości aktualnego rekordu do strumienia stdout (tj. nie podanie żadnej akcji jest równoważne akcji print).
  • Znaki białe są na ogół bez znaczenia, z tym że koniec linii zazwyczaj brany jest za koniec polecenia. Zaleca się użycie średnika jako końca jednostki składniowej. Bloki (polecenia złożone) ujmowane są w nawiasy klamrowe, jak w C.
  • Komentarze zaczynają się od # i kończą z końcem linii.

Postać wzorców

  • BEGIN, END -- wzorce specjalne, traktowane jako nie pasujące do żadnego rekordu. Efektem ich użycia jest wykonanie odp. akcji jeden raz, przed rozpoczęciem przetwarzania danych (BEGIN) lub po jego zakończeniu (END). Mogą występować w programie dowolnie wiele razy i w dowolnych pozycjach; użyteczne akcje dla tych wzorców to np. inicjalizacja zmiennych (BEGIN), wypisywanie nagłówków tabeli lub podsumowań.
  • /wyrażenie regularne/ -- zgodne z nim są rekordy pasujące jako napisy do podanego wyrażenia regularnego; składnia wyrażeń regularnych jest w zasadzie analogiczna jak w przypadku stosowanych z programem (e)grep.
  • dowolne wyrażenie języka Awk -- jego wartość obliczana jest na nowo dla każdego wczytanego rekordu danych, a akcja jest wykonywana gdy wartość wyrażenia jest niezerowa (dla wyrażeń arytmetycznych) lub niepusta (dla wyrażeń napisowych)
  • Wzorzec1, Wzorzec2 -- para wzorców przedzielonych przecinkiem pasuje do wszystkich rekordów począwszy od pierwszego pasującego do Wzorzec1 a skończywszy na ostatnim pasującym do Wzorzec2

Składnia wyrażeń

  • Wyrażenia arytmetyczne budowane są ze stałych liczbowych oraz zmiennych o wartościach liczbowych, z wykorzystaniem operatorów arytmetycznych (+, -, *, ^, /, %) (^ == potęgowanie, % == reszta z dzielenia)
  • Wyrażenia przypisania oraz inkrementacji: po lewej stronie operatora przypisania wartości (=, +=, -=, *=, /=, %=, ^=) może stać nazwa zmiennej skalarnej, odwołanie do elementu tablicy (p. dalej), lub odwołanie do pola bieżącego rekordu (//$n//). Po prawej stronie: dowolne wyrażenie. Wartością wyrażenia przypisania jest wartość która zostaje przypisana. Podobnie działają operatory inkrementacji, o własnościach analogicznych jak w C (++, --).
  • Wyrażenia napisowe -- stała napisowa ma postać napisu ujętego w cudzysłów ("napis"). Jedyną operacją tworzącą napis złożony jest konkatenacja (łączenie) stałych napisowych lub zmiennych o wartościach napisowych. Operator konkatenacji nie posiada oznaczenia, zaleca się jednak stosowanie nawiasów np. ("napis1" "napis2") == "napis1napis2"
  • Wyrażenia logiczne buduje się z wyrażeń arytmetycznych i napisowych za pomocą operatorów porównywania (==, !=, <, <=, >=) i operatorów logicznych (&&, ||, !); operatory porównywania dla wyrażeń arytmetycznych działają analogicznie jak w języku C; napisy są porównywane leksykograficznie. Wartością wyrażenia logicznego jest liczba 1 (prawda) lub 0 (fałsz), znów podobnie jak w C. Jako argument wyrażenia logicznego, każda niezerowa liczba i każdy niepusty napis traktowane są jako równoważne 1. Napisowi pustemu odpowiada wartość logiczna fałsz (0). Innym elementem służącym do tworzenia wyrażeń logicznych są operatory dopasowania wyrażeń regularnych (~, !~); po lewej stronie przyjmują one wyrażenia o wartości napisowej, po prawej może wystąpić stałe wyrażenie regularne (/REGEXP/) lub wyrażenie o wartości napisowej, które zostanie potraktowane jako zapis wyrażenia regularnego (umożliwia to wykorzystywanie dynamicznie utworzonych wyrażeń regularnych).
  • Wyrażenia warunkowe -- tworzone są za pomocą konstrukcji WYR1 ? WYR2 : WYR3 o znaczeniu analogicznym jak w C.
  • Wywołania funkcji: mają postać funkcja(arg1, arg2, ...). Spacja przed otwarciem nawiasu jest niedozwolona! Awk posiada wbudowany zestaw standardowych funkcji matematycznych (sqrt, exp, log, sin, cos, atan2, rand, srand, int>/tt>). Istnieją również wbudowane funkcje operujące na napisach (index, length, match, split, sprintf, sub, gsub, gensub, substr, tolower, toupper), funkcje I/O (close, system), oraz funkcje związane z czasem (systime, strftime). Możliwe jest też definiowanie własnych funkcji w tekście programu.
  • Definicja funkcji ma postać:
function NAZWA(PARAMETRY)
       {
       DEFINICJA
       }
  • W liście parametrów PARAMETRY należy uwzględnić zarówno parametry formalne funkcji, jak i jej zmienne lokalne; przy wywołaniu PARAMETRY inicjalizowane są kolejno wartościami parametrów aktualnych, a brakujące otrzymują jako wartość napis pusty. Definicje funkcji używanych w programie awk nie muszą występować przed ich użyciem.

Instrukcje sterujące

if (WARUNEK) AKCJA1 ; [ else AKCJA2 ]

while (WARUNEK) AKCJA

do AKCJA while (WARUNEK)

for (INICJALIZACJA, WARUNEK, INKREMENTACJA) AKCJA

break

continue

exit [KOD ZWRACANY]

Powyższe instrukcje sterujące działają analogicznie jak w języku C.

Uwaga: po wywołaniu exit, akcje odpowiadające wzorcom END wykonywane.

next : powoduje przejście do przetwarzania kolejnego rekordu, z zaniechaniem dalszego przetwarzania rekordu bieżącego.


Adresowanie rekordów i pól

  • $0 : zawartość bieżącego rekordu
  • $n (dla n>0): zawartość n-tego pola bieżącego rekordu (jeżeli n przekracza indeks ostatniego pola w bieżącym rekordzie: napis pusty)

po znaku $ można umieścić wyrażenie arytmetyczne, niekoniecznie stałą (wyrażenia złożone należy obejmować nawiasami)

Zmienne specjalne

(podane zostaną tylko najczęściej używane)

  • FS : separator pól (w danych wejściowych); napis jednoznakowy lub wyrażenie regularne. Domyślna wartość FS == " " ma specjalne znaczenie: separatorami są dowolnie długie ciągi spacji i kodów tabulacji (a więc zawartości pól nie będą miały spacji na początku ani na końcu). Wartość FS == "" (pusty napis) oznacza, że każdy znak rekordu będzie potraktowany jako pole.
  • RS : separator rekordów (w danych wejściowych). Domyślna wartość: znak nowej linii. Wartość RS == "" oznacza, że rekordy są rozdzielone dowolnie długimi ciągami pustych linii.
  • OFS, ORS : pełnią analogiczną rolę do FS, RS dla strumienia danych wyjściowych (wyprowadzanych instrukcją print, p. dalej).
  • ARGC, ARGV : analogiczne do argc, argv w języku C, z tym, że nie uwzględniają opcji interpretowanych przez program awk (a jedynie nazwy plików podane na linii komend). Tablica ARGV indeksowana jest liczbami całkowitymi, od zera począwszy.
  • NF : liczba pól w bieżącym rekordzie.
  • NR/tt> : numer kolejny aktualnie przetwarzanego rekordu.
  • FILENAME : nazwa aktualnie przetwarzanego pliku. FILENAME == "-" jeżeli dane pochodzą ze strumienia stdin.

Tablice

Alokacja zmiennych tablicowych w języku Awk jest automatyczna; nie istnieje deklaracja tablicy. Odwołanie do elementu tablicy ma postać NAZWA[INDEKS] i może występować zarówno po prawej, jak i po lewej stronie wyrażenia przypisania wartości zmiennej.

INDEKS może być dowolnym wyrażeniem skalarnym --- czyli o wartości liczbowej lub napisowej.

Odwołanie do nieprzypisanego elementu zwraca napis pusty (i przypisuje go jako wartość danemu elementowi tablicy).

Wyrażenie INDEKS in NAZWA zwraca prawdę (1) jeżeli NAZWA[INDEKS] posiada przypisaną wartość, fałsz (0) w wypadku przeciwnym.

Konstrukcja for (INDEKS in NAZWA) AKCJA umożliwia przeskanowanie wszystkich elementów tablicy NAZWA którym przypisano wartości.

delete NAZWA[INDEKS] usuwa element z tablicy (a nie przypisuje mu pusty napis!).

Wyprowadzanie danych

      print ARG1, ARG2, ...
      printf FORMAT, ARG1, ARG2, ...

== Składnia wywołania

      awk OPCJE -f PLIK.PROGRAMU PLIKI ...
      awk OPCJE 'tekst programu' PLIKI ...


Istnieje m. in. opcja umożliwiająca zmianę separatora pól (-F FS).

Możliwe jest ponadto przypisywanie wartości zmiennym Awk-a na linii poleceń: argumenty postaci NAZWA=WARTOSC są rozpoznawane jako wyrażenia przypisania i mają identyczny skutek jak zamieszczenie odp. przypisania jako akcji dla wzorca BEGIN (ale po wykonaniu akcji BEGIN zamieszczonych w tekście lub pliku programu). Argumenty postaci NAZWA=WARTOSC są (podobnie jak nazwy plików danych) umieszczane w tablicy ARGV.

Powrót


--RobertJB (dyskusja) 21:13, 21 lis 2018 (CET)