AWK
 |
| Pojawienie się | 1977 |
|---|
| Paradygmat | skryptowy,proceduralny,sterowany zdarzeniami |
|---|
| Typowanie | brak; ciągi znaków, liczby całkowite i zmiennoprzecinkowe; wyrażenia regularne |
|---|
| Implementacje | awk, GNU Awk, mawk, nawk, MKS AWK, Thompson AWK (compiler), Awka (compiler) |
|---|
| Aktualnawersja stabilna | IEEE Std 1003.1-2004 (POSIX) / 1985 |
|---|
| Twórca | Alfred Aho,Peter Weinberger(inne języki),Brian Kernighan |
|---|
| Platforma systemowa | wieloplatformowy |
|---|
AWK – interpretowanyjęzyk programowania, którego główną funkcją jest wyszukiwanie i przetwarzanie wzorców wplikach lub strumieniach danych. Jest także nazwą programu początkowo dostępnego dlasystemów operacyjnych będących pochodnymiUNIX-a, obecnie także na inne platformy.
AWK jest językiem, który w znacznym stopniu wykorzystujetablice asocjacyjne,stringi iwyrażenia regularne. Nazwa języka pochodzi od pierwszych liter nazwisk jego autorówAlfreda V. Aho,Petera Weinbergera(inne języki) iBriana Kernighana. Bywa zapisywana małymi literami, odczytywana jako jedno słowoawk, wymawiana jak pierwsza sylaba wawkward.
Definicja języka AWK jest zawarta wPOSIX 1003.2 Command Language And Utilities Standard. Wersja ta jest z kolei oparta na opisie zThe AWK Programming Language napisanym przez Aho, Weinbergera i Kernighana, z dodatkowymi właściwościami zdefiniowanymi w wersji awk zSVR4.
Wwierszu poleceń podaje się opcje dla awk, tekst programu (jeśli nie podano go poprzez opcję-f lub--file) i wartości, które mają być udostępnione w predefiniowanych zmiennychARGC iARGV.
„AWK jest językiem służącym do przetwarzania plików tekstowych. Plik jest traktowany jako ciąg rekordów, przy czym domyślnie rekordem jest każdy wiersz. Każda linia jest podzielona na pola, więc można traktować pierwsze pole linii jako pierwsze słowo, drugie pole jako drugie słowo itd. Program AWK składa się z sekwencji instrukcji wzorzec-akcja. AWK czyta wejście linia po linii. Każda linia jest przeszukiwana pod kątem wzorców występujących w programie i dla każdego pasującego wzorca wykonywana jest akcja z nim skojarzona.” – Alfred V. Aho[1]
Program AWK składa się z sekwencji instrukcji wzorzec-akcja oraz opcjonalnych definicji funkcji.
wzorzec {instrukcje akcji }functionnazwa(lista parametrów) {instrukcje }gdziewzorzec to zwykle jakieś wyrażenie, aakcja – lista komend. Wejście dzielone jest na rekordy, domyślnie oddzielone znakiem nowej linii.Dla każdego rekordu wejścia awk dokonuje porównania, sprawdzając czy odpowiada on jakiemuś wzorcowi z programu AWK. Jeśli wzorzec będzie odpowiadał rekordowi, zostanie wykonana związana z nim akcja. Wzorce są sprawdzane w kolejności ich pojawienia się w programie. Domyślną akcją jest wypisanie rekordu.
Na komendy AWK składają się wywołania funkcji, nadawanie wartości zmiennym, obliczenia lub jakaś kombinacja wymienionych zadań. AWK posiada wbudowane wsparcie dla wielu funkcji. Niektóre wersje pozwalają nadynamiczne linkowanie bibliotek, co umożliwia korzystanie z jeszcze większej liczby funkcji.Dla uproszczenia nawiasy klamrowe ({}) w poniższych przykładach zostaną pominięte.
Polecenieprint jest używane do wypisywania tekstu. Wyjście jest zawsze zakończone predefiniowanym separatorem rekordów (output record separator (ORS)), który domyślnie jest znakiem nowej linii. Najprostsze zastosowanie poleceniaprint to:
print- Wyświetla zawartość obecnego rekordu.
W AWK rekordy rozbijane są napola, które można wyświetlić osobno:
print $1- Wyświetla pierwsze pole obecnego rekordu.
print $1, $3- Wyświetla pierwsze i trzecie pole obecnego rekordu oddzielone separatorem pola (output field separator (OFS)) – domyślniespacją.
Choć zapis pól ($X) może kojarzyć się z zapisem określającym zmienne (jak np. wperlu), to jednak określa pola bieżącego rekordu. Ponadto$0 odnosi się do całego rekordu, więc "print" oraz "print $0" mają takie samo działanie.
print pozwala również wyświetlić wynik obliczeń lub wywołania funkcji. Np.
print 3+2print foobar(3)print foobar(zmienna)print sin(3-2)
Wyjście można również przekierować do pliku:
print "wyrażenie" > "nazwa pliku"
lub do innego polecenia przez użyciepotoku:
print "wyrażenie" | "polecenie"
Zmienne AWK są dynamiczne — zaczynają istnieć, gdy są po raz pierwszy użyte. Nazwy zmiennych mogą zawierać znaki z zakresu[A-Za-z0-9_], lecz nie mogą być słowami kluczowymi. Zmienne oraz pola mogą być liczbami (zmiennoprzecinkowymi), łańcuchami lub jednym i drugim naraz. Interpretacja wartości zmiennej zależy od kontekstu. Jeśli jest użyta w wyrażeniu numerycznym, jest interpretowana jako liczba. Natomiast jeśli jest użyta w wyrażeniu łańcuchowym — jest traktowana jak łańcuch.
AWK posiada tablice jednowymiarowe. Symulowane mogą być również tablice wielowymiarowe. Podczas działania programu ustawianych jest kilka predefiniowanych zmiennych opisanych niżej.
Zmienne wbudowane w AWK to m.in. zmienne określające pola:$1,$2 itd. Zwracają one wartość lub tekst przechowywany aktualnie w określonym polu rekordu. Poza nimi AWK posiada również inne zmienne:
| Zmienna | Zastosowanie |
|---|
FILENAME | Zawiera nazwę pliku wejściowego. |
FS | Przechowuje separator pól rekordu (field separator). Domyślnie jest to biały znak, czyli spacja lub znak tabulacji. FS można przypisać inną wartość określającą nowy separator. |
RS | Przechowuje separator rekordów (record separator). Jako że domyślnie każda linia jest nowym rekordem, domyślna wartość RS to znak nowej linii. |
NF | Liczba pól w bieżącym rekordzie wejściowym. Przy pomocy tej zmiennej można odwołać się do ostatniego pola rekordu. W tym celu wystarczy wpisać$NF |
NR | Całkowita liczba odczytanych do tej pory rekordów wejściowych. |
OFS | Separator pól wyjściowych (output field separator). Domyślnie jest to spacja. |
ORS | Separator rekordów wyjściowych (output record separator), oddzielający drukowane rekordy. Domyślnie jest to nowa linia. |
OFMT | Przechowuje format wyjściowy liczb, domyślnie "%.6g". |
SUBSEP | Znak, używany do separacji wielokrotnych indeksów w elementach tablicowych, domyślnie jest to "\034". |
Tablice są indeksowane wyrażeniem ujętym w nawiasy kwadratowe ([]). Jeśli wyrażenie jest listą wyrażeń (wyrażenie, wyrażenie, ...), to indeks tablicy jest sklejany z wartości (łańcuchowych) każdego wyrażenia, oddzielonych wartością zmiennejSUBSEP. Jest tak dlatego, że AWK posiada wyłącznietablice asocjacyjne, zaś klucze numeryczne pamiętane są jako łańcuchy.
Symulowanie tablic wielowymiarowych polega na sklejaniu poszczególnych indeksów w unikalny łańcuch. Na przykład:
i="A";j="B";k="C"x[i,j,k]="hello, world\n"
przypisuje łańcuch "hello, world\n" elementowi tablicyx, o indeksie będącym łańcuchem "A\034B\034C".
Jeśli tablica posiada wielokrotne indeksy, można użyć konstrukcji(i, j) in array. Element można skasować z tablicy przy użyciu poleceniadelete. Poleceniemdelete można się też posłużyć do skasowania całej zawartości tablicy, przez podanie jej nazwy bez indeksu.
Funkcje są wykonywane po wywołaniu ich z wyrażeń występujących we wzorcach lub akcjach. Definicja funkcji składa się ze słowa kluczowegofunction, jej nazwy, argumentów i ciała. Poniżej znajduje się przykład funkcji:
functiondodaj_siedem(liczba){returnliczba+7}Tę funkcję można wywołać w następujący sposób:
printdodaj_siedem(51)# zwraca 58
Między nazwą funkcji a nawiasem otwierającym można wstawić spację jedynie podczas jej deklaracji – w wywołaniunawias musi stać bezpośrednio po nazwie funkcji. Ma to na celu zapobieżenie niejednoznaczności składni z operatoremkonkatenacji (łączenia). Ograniczenie to nie odnosi się do funkcji wbudowanych.
Funkcje mogą posiadać zmienne lokalne. Ich nazwy dodawane są na końcu listy argumentów w definicji funkcji. Jednak ich wartości powinno się pomijać wywołując daną funkcję. Zazwyczaj przed deklaracją zmiennych lokalnych dodaje się kilkabiałych znaków, by wskazać miejsce, w którym kończą się argumenty funkcji i zaczynają zmienne lokalne.
Zamiast słowafunction można używać słowafunct.
Operatory w AWK, w kolejności malejącego priorytetu, to:
| Operator | Znaczenie |
|---|
(...) | Grupowanie |
$ | Odniesienie się do pola |
++ -- | Inkrementuj i dekrementuj, zarówno przedrostkowe i przyrostkowe |
^ | Potęgowanie (można użyć również **, oraz **= dla operatora przypisania) |
+ - ! | Jednoargumentowy plus, minus i logiczna negacja |
* / % | Mnożenie, dzielenie imodulo |
+ - | Dodawanie i odejmowanie |
' ' (odstęp) | Konkatenacja (złączenie) łańcuchów |
< > <= >= != == | Regularne operatory relacyjne |
~ !~ | Dopasowanie wyrażenia regularnego, dopasowanie zanegowane |
in | Przynależność do tablicy |
&& | Koniunkcja logiczna AND |
|| | Alternatywa logiczna OR |
?: | Wyrażenie warunkowe zC. Ma ono postaćwyraż1 ? wyraż2 : wyraż3. Jeśli wyraż1 jest prawdziwe, to wartością wyrażenia jestwyraż2, w przeciwnym wypadku jest niąwyraż3. Obliczane jest wyłącznie jedno zwyraż2 iwyraż3 |
= += -= *= /= %= ^= | Przypisanie. Obsługiwane jest zarówno przypisanie absolutne (zmienna = wartość) jak i przypisanie operatorowe (inne formy) |
Tekst programu czytany jest tak, jakby wszystkie pliki programu zostały połączone ze sobą w całość, przy czym pierwszeństwo mają pliki podane jako argumenty polecenia. Przydaje się to do budowaniabibliotek funkcji AWK, bez konieczności włączania ich do każdego nowego programu AWK, który z nich korzysta. Umożliwia to również łączenie funkcji bibliotecznych z programami z wiersza poleceń. Zmienna środowiskowaAWKPATH określa ścieżkę przeszukiwania, używaną do znajdowania plików źródłowych podanych w opcji-f. Jeśli zmienna ta nie istnieje, domyślną ścieżką staje się.:/usr/local/share/awk. (Faktyczny katalog może być różny, zależnie od tego jak skompilowano i zainstalowano awk). Jeśli nazwa pliku, podana opcji-f zawiera znak/, nie jest dokonywane żadne przeszukiwanie ścieżki.
Program AWK wykonywany jest w następującej kolejności:
- inicjalizacja zmiennych podanych w opcjach
-v, - kompilacja do postaci wewnętrznej,
- wywołanie kodu zawartego w blokach
BEGIN (o ile istnieją), - odczytywanie plików podanych w tablicy
ARGV, - odczytywanie standardowego wejścia, jeśli pliki nie zostały podane.
Z poziomu wiersza poleceń można także ustawić wartość zmiennej, podając zamiast nazwy pliku ciągzmienna=wartość. Ten sposób inicjalizowania zmiennych najbardziej przydaje się do dynamicznego nadawania wartości zmiennym, których AWK używa do określania sposobu, w jaki wejście rozbijane jest na pola i rekordy. Jest też użyteczny do kontroli stanu, jeśli zachodzi potrzeba wielokrotnego czytania danego pliku danych. Jeśli wartość konkretnego elementuARGV jest pusta (""), to awk ją pomija.
Poniżej znajduje się przykład programu "Hello world" napisanego w AWK:
BEGIN{print"Hello, world!"}Niekoniecznie trzeba w tym wypadku pisać na końcuexit. Jedynym wzorcem jestBEGIN, więc żadne argumenty z linii komend nie są przetwarzane.W niektórych wersjach AWK i niektórych krajach dodanie znaku”_“ przed łańcuchem znaków wypisze go w języku narodowym. Np.
BEGIN{print_"Hello, world!"}weFrancji może wypisaćbonjour, monde!.
Program liczy liczbę słów na wejściu i wypisuje liczbę słów, linii i znaków podanych na wejściu (podobnie jakwc).
{w+=NFc+=length+1}END{printNR,w,c}Ze względu na brak wzorca w pierwszej linii programu akcja jest wykonywana dla każdego wiersza wejścia.
s jest zwiększane o numer ostatniego słowa w każdym rekordzie.Na końcu wejścia wzorzecEND pasuje, więcs jest wypisywane. Jednak wejście może nie zawierać ani jednej linii. Wtedy, jako że zmiennejs nie została nadana żadna wartość, będzie to pusty ciąg. Dodanie zera na końcu przy wypisywanius wymusza traktowanie zmiennej tak, jakby zawierała ona liczbę. Dzięki temu nawet, gdys jest pustym ciągiem na wyjściu nie będzie pustej linii, lecz0.
$ yes Wikipedia | awk 'NR % 4 == 1, NR % 4 == 3 { printf "%6d %s\n", NR, $0 }' | sed 7q 1 Wikipedia 2 Wikipedia 3 Wikipedia 5 Wikipedia 6 Wikipedia 7 Wikipedia 9 Wikipedia$Tutaj komendayes wypisuje słowo „Wikipedia” tak długo, ażsed wykryje, że zostało wypisanych 7 linii. Dalsza część polecenia wypisuje każdą z linii poprzedzoną jej numerem. Wypisywane są tylko linie, których numery dają resztę z dzielenia przez 4 o wartościach od 1 do 3.
Program używatablicy asocjacyjnej:
BEGIN{FS="[^a-zA-Z]+"}{for(i=1;i<=NF;i++)words[tolower($i)]++}END{for(iinwords)printi,words[i]}BlokBEGIN ustawia separator pola na dowolny znak niebędący literą. Warto zauważyć, że separatory mogą być też wyrażeniami regularnymi.Następnie następuje akcja wykonywana na każdej linii wejścia: dla każdego pola linii zwiększana jest liczba razy, jaką to słowo (uprzednio zamienione na małe litery) wystąpiło. Na końcu wypisywane są wszystkie słowa wraz z częstotliwościami występowania.
Podobnie jak w wielu innych językach skrypt AWK można napisać poprzedzając go znakiem „shebang”. Dla przykładu komendęhello.awk wypisującą tekst „Hello, world!” można napisać tworząc plik o nazwiehello.awk posiadający następującą zawartość:
#! /usr/bin/awk -fBEGIN{print"Hello, world!"}Opcja-f informuje awk, że następny argument to nazwa pliku, z którego należy przeczytać program, a jest on tam umieszczany przezpowłokę systemową podczas działania, tak jakby wywołane zostało polecenie/usr/bin/awk -f hello.awk.
| System plików | |
|---|
| Procesy | |
|---|
| Środowisko użytkownika | |
|---|
| Przetwarzanie tekstu | |
|---|
| Wbudowane w powłokę | |
|---|
| Komunikacja | |
|---|
| Wyszukiwanie | |
|---|
| Dokumentacja | |
|---|
| Różne | |
|---|