Awk jest językiem skryptowym ogólnego przeznaczenia przeznaczonym do zaawansowanego przetwarzania tekstu. Jest najczęściej używany jako narzędzie do raportowania i analizy.
w przeciwieństwie do większości innych języków programowania, które są proceduralne, awk jest oparty na danych, co oznacza, że definiujesz zestaw działań, które mają być wykonywane na tekście wejściowym. Pobiera dane wejściowe, przekształca je i wysyła wynik na standardowe wyjście.
Ten artykuł obejmuje podstawy języka programowania awk., Znajomość podstaw awk znacznie poprawi możliwość manipulowania plikami tekstowymi w wierszu poleceń.
jak działa awk #
istnieje kilka różnych implementacji awk. Użyjemy GNU implementacji awk, która nazywa się gawk. W większości systemów Linux interpreter awk
jest tylko dowiązaniem symbolicznym do gawk
.
rekordy i pola #
Awk może przetwarzać pliki i strumienie danych tekstowych. Dane wejściowe są podzielone na rekordy i pola. Awk działa na jednym rekordzie na raz, aż do osiągnięcia końca wejścia., Rekordy są oddzielone znakiem zwanym separatorem rekordów. Domyślnym separatorem rekordów jest znak nowej linii, co oznacza, że każda linia danych tekstowych jest rekordem. Nowy separator rekordów można ustawić za pomocą zmiennej RS
.
rekordy składają się z pól, które są oddzielone separatorem pól. Domyślnie pola są oddzielone białą spacją, w tym jedną lub więcej tabulatorów, spacją i znakami nowej linii.
do pól w każdym rekordzie odnosi się znak dolara ($
), a następnie numer pola, rozpoczynający się od 1., Pierwsze pole jest reprezentowane przez $1
, drugie przez $2
I tak dalej. Ostatnie pole może być również odwołane do specjalnej zmiennej $NF
. Cały rekord można odwołać się do $0
.
oto wizualna reprezentacja pokazująca, jak odwoływać się do rekordów i pól:
tmpfs 788M 1.8M 786M 1% /run/lock /dev/sda1 234G 191G 31G 87% /|-------| |--| |--| |--| |-| |--------| $1 $2 $3 $4 $5 $6 ($NF) --> fields|-----------------------------------------| $0 --> record
program Awk #
aby przetworzyć tekst za pomocą awk
, piszesz program, który mówi komendzie, co ma robić., Program składa się z szeregu reguł i funkcji zdefiniowanych przez użytkownika. Każda reguła zawiera jeden wzór i parę akcji. Reguły są oddzielone znakiem nowego wiersza lub średnikiem (;
). Zazwyczaj program awk wygląda tak:
pattern { action }pattern { action }...
gdy awk
przetwarza dane, jeśli wzorzec pasuje do rekordu, wykonuje określoną akcję na tym rekordzie. Gdy reguła nie ma wzorca, wszystkie rekordy (linie) są dopasowane.
akcja awk jest zamknięta w klamrach ({}
) I składa się z instrukcji., Każda instrukcja określa operację do wykonania. Akcja może mieć więcej niż jedną instrukcję oddzieloną znakami nowej linii lub średnikami (;
). Jeśli reguła nie ma akcji, domyślnie drukuje cały rekord.
Awk obsługuje różne typy instrukcji, w tym wyrażenia, warunki, polecenia wejściowe, wyjściowe i inne. Najczęstsze polecenia awk to:
-
exit
– zatrzymuje wykonywanie całego programu i kończy działanie., -
next
– zatrzymuje przetwarzanie bieżącego rekordu i przechodzi do następnego rekordu w danych wejściowych. -
print
– drukuje rekordy, pola, zmienne i niestandardowy tekst. -
printf
– daje większą kontrolę nad formatem wyjściowym, podobnym do C i bashprintf
.
podczas pisania programów awk wszystko po znaku skrótu (#)
I do końca wiersza jest uważane za komentarz., Długie linie mogą być podzielone na wiele linii za pomocą znaku kontynuacji, odwrotny ukośnik (\
).
uruchamianie programów awk #
program awk można uruchomić na kilka sposobów. Jeśli program jest krótki i prosty, może być przekazany bezpośrednio do interpretera awk
w wierszu poleceń:
awk 'program' input-file...
podczas uruchamiania programu w wierszu poleceń powinien być zamknięty w pojedynczych cudzysłowach (''
), więc powłoka nie interpretuje programu.,
Jeśli program jest duży i złożony, najlepiej umieścić go w pliku i użyć opcji -f
, aby przekazać plik do polecenia awk
:
awk -f program-file input-file...
w poniższych przykładach będziemy użyj pliku o nazwie „zespoły.txt”, który wygląda jak ten poniżej:
Bucks Milwaukee 60 22 0.732 Raptors Toronto 58 24 0.707 76ers Philadelphia 51 31 0.622Celtics Boston 49 33 0.598Pacers Indiana 48 34 0.585
wzorce Awk #
wzorce w awk kontrolują, czy powiązana akcja ma być wykonywana, czy nie.,
Awk obsługuje różne typy wzorców, w tym wyrażenia regularne, wyrażenia relacji, zakres i specjalne wzorce wyrażeń.
gdy reguła nie ma wzorca, każdy rekord wejściowy jest dopasowany. Oto Przykład reguły zawierającej tylko akcję:
awk '{ print $3 }' teams.txt
program wyświetli trzecie pole każdego rekordu:
6058514948
wzorce wyrażeń regularnych #
Wyrażenie regularne lub regex jest wzorcem, który pasuje do zestawu łańcuchów., Wzorce wyrażeń regularnych Awk są zamknięte w ukośnikach (//
):
/regex pattern/ { action }
najbardziej podstawowym przykładem jest literalne dopasowanie znaków lub łańcuchów znaków. Na przykład, aby wyświetlić pierwsze pole każdego rekordu zawierającego „0.5”, należy uruchomić następujące polecenie:
awk '/0.5/ { print $1 }' teams.txt
CelticsPacers
wzorzec może być dowolnym typem rozszerzonego wyrażenia regularnego., Oto przykład, który wyświetla pierwsze pole, jeśli rekord zaczyna się od dwóch lub więcej cyfr:
awk '/^/ { print $1 }' teams.txt
76ers
wzorce wyrażeń relacyjnych #
wzorce wyrażeń relacyjnych są zwykle używane do dopasowania zawartości określonego pola lub zmiennej.
domyślnie wzorce wyrażeń regularnych są dopasowywane do rekordów. Aby dopasować Wyrażenie regularne do pola, określ pole i użyj operatora porównania „contain” (~
) względem wzorca.,
na przykład, aby wydrukować pierwsze pole każdego rekordu, którego drugie pole zawiera „ia”, wpisz:
awk '$2 ~ /ia/ { print $1 }' teams.txt
76ersPacers
aby dopasować pola, które nie zawierają danego wzorca, użyj !~
operator:
awk '$2 !~ /ia/ { print $1 }' teams.txt
BucksRaptorsCeltics
Możesz porównać łańcuchy lub liczby dla relacji takich jak, większe, mniejsze, Równe i tak dalej., Poniższe polecenie wyświetla pierwsze pole wszystkich rekordów, których trzecie pole jest większe niż 50:
awk '$3 > 50 { print $1 }' teams.txt
BucksRaptors76ers
wzorce zakresu #
wzorce zakresu składają się z dwóch wzorców oddzielonych przecinkiem:
pattern1, pattern2
wszystkie rekordy począwszy od rekordu, który pasuje do pierwszego wzorca, aż do rekordu, który pasuje do drugiego wzorca, są dopasowane.,
oto przykład, który wyświetli pierwsze pole wszystkich rekordów począwszy od rekordu zawierającego „Raptors” aż do rekordu zawierającego „Celtics”:
awk '/Raptors/,/Celtics/ { print $1 }' teams.txt
Raptors76ersCeltics
wzorce mogą być również wyrażeniami relacji. Poniższe polecenie wyświetli wszystkie rekordy począwszy od tego, którego czwarte pole jest równe 32, aż do tego, którego czwarte pole jest równe 33:
awk '$4 == 31, $4 == 33 { print $0 }' teams.txt
76ers Philadelphia 51 31 0.622Celtics Boston 49 33 0.598
wzorce zakresów nie mogą być łączone z innymi wyrażeniami wzorców.,
specjalne wzorce wyrażeń #
Awk zawiera następujące specjalne patteny:
-
BEGIN
– używane do wykonywania akcji przed przetworzeniem rekordów. -
END
– służy do wykonywania akcji po przetworzeniu rekordów.
wzorzecBEGIN
jest zwykle używany do ustawiania zmiennych, a wzorzecEND
do przetwarzania danych z rekordów, takich jak obliczenia.
poniższy przykład wyświetli „rozpocznij przetwarzanie.”, następnie wydrukuj trzecie pole każdego rekordu i na koniec ” Zakończ przetwarzanie.,”:
awk 'BEGIN { print "Start Processing." }; { print $3 }; END { print "End Processing." }' teams.txt
Start Processing6058514948End Processing.
Jeśli program ma tylko wzorzecBEGIN
, akcje są wykonywane, a wejście nie jest przetwarzane. Jeśli program ma tylko wzorzec END
, dane wejściowe są przetwarzane przed wykonaniem akcji reguły.
wersja Gnu awk zawiera również dwa specjalne wzorce BEGINFILE
I ENDFILE
, które umożliwiają wykonywanie akcji podczas przetwarzania plików.,
łączenie wzorców #
Awk umożliwia łączenie dwóch lub więcej wzorców za pomocą operatora logicznego i (&&
) oraz operatora logicznego lub (||
).,
oto przykład, który używa operatora &&
do drukowania pierwszego pola rekordu, którego trzecie pole jest większe niż 50, a czwarte jest mniejsze niż 30:
awk '$3 > 50 && $4 < 30 { print $1 }' teams.txt
BucksRaptors
wbudowane zmienne #
awk posiada wiele wbudowanych zmiennych, które zawierają przydatne informacje i pozwalają kontrolować jak program jest przetwarzany. Poniżej znajdują się niektóre z najczęściej wbudowanych zmiennych:
-
NF
-liczba pól w rekordzie., -
NR
– numer bieżącego rekordu. -
FILENAME
– nazwa aktualnie przetwarzanego pliku wejściowego. -
FS
– separator pól. -
RS
– separator rekordów. -
OFS
– Separator pola wyjściowego. -
ORS
– Separator rekordów wyjściowych.,
oto przykład pokazujący, jak wydrukować nazwę pliku i liczbę wierszy (rekordów):
awk 'END { print "File", FILENAME, "contains", NR, "lines." }' teams.txt
File teams.txt contains 5 lines.
zmienne w AWK można ustawić w dowolnej linii w programie. Aby zdefiniować zmienną dla całego programu, umieść ją we wzorze BEGIN
.
Zmiana separatora pól i rekordów #
domyślną wartością separatora pól jest dowolna liczba znaków spacji lub tabulacji. Można ją zmienić poprzez ustawienie w zmiennej FS
.,
na przykład, aby ustawić separator pól na .
należy użyć:
awk 'BEGIN { FS = "." } { print $1 }' teams.txt
Bucks Milwaukee 60 22 0Raptors Toronto 58 24 076ers Philadelphia 51 31 0Celtics Boston 49 33 0Pacers Indiana 48 34 0
separator pól może być również ustawiony na więcej niż jeden znak:
awk 'BEGIN { FS = ".." } { print $1 }' teams.txt
podczas uruchamiania jednowierszowych awk w wierszu poleceń można również użyć opcji -F
aby zmienić separator pól:
awk -F "." '{ print $1 }' teams.txt
domyślnie separator rekordów jest znakiem nowej linii i można go zmienić za pomocą RS
,
oto przykład pokazujący, jak zmienić separator rekordów na .
:
awk 'BEGIN { RS = "." } { print $1 }' teams.txt
Bucks Milwaukee 60 22 0732 Raptors Toronto 58 24 0707 76ers Philadelphia 51 31 0622Celtics Boston 49 33 0598Pacers Indiana 48 34 0585
akcje Awk #
akcje Awk są zamknięte w klamrach ({}
) I wykonywane, gdy wzór pasuje. Akcja może mieć zero lub więcej poleceń. Wiele poleceń jest wykonywanych w takiej kolejności, w jakiej się pojawiają i muszą być oddzielone znakami nowej linii lub średnikami (;
).,
istnieje kilka rodzajów instrukcji akcji, które są obsługiwane w awk:
- wyrażenia, takie jak przypisywanie zmiennych, operatory arytmetyczne, operatory przyrostowe i dekrementacyjne.
- instrukcje sterujące, używane do sterowania przepływem programu (
if
,for
,while
,switch
I inne) - instrukcje wyjściowe, takie jak
print
Iprintf
. - wyrażenia złożone, do grupowania innych wyrażeń.,
- polecenia wejściowe, do sterowania przetwarzaniem danych wejściowych.
- Instrukcje usuwania, do usuwania elementów tablicy.
print
jest prawdopodobnie najczęściej używaną instrukcją awk. Drukuje sformatowane wyjście tekstu, rekordów, pól i zmiennych.
podczas drukowania wielu elementów należy oddzielić je przecinkami., Oto przykład:
awk '{ print $1, $3, $5 }' teams.txt
wydrukowane elementy są oddzielone pojedynczymi spacjami:
Bucks 60 0.732Raptors 58 0.70776ers 51 0.622Celtics 49 0.598Pacers 48 0.585
Jeśli nie użyjesz przecinków, nie będzie spacji między elementami:
awk '{ print $1 $3 $5 }' teams.txt
wydrukowane elementy są konkatenowane:
Bucks600.732Raptors580.70776ers510.622Celtics490.598Pacers480.585
gdy print
jest używany bez argumentu, domyślnie jest to print $0
. Aktualny rekord jest drukowany.,
aby wydrukować niestandardowy tekst, musisz zacytować tekst z podwójnym cudzysłowem:
awk '{ print "The first field:", $1}' teams.txt
The first field: BucksThe first field: RaptorsThe first field: 76ersThe first field: CelticsThe first field: Pacers
Możesz również wydrukować znaki specjalne, takie jak nowa linia:
awk 'BEGIN { print "First line\nSecond line\nThird line" }'
First lineSecond lineThird line
instrukcja printf
daje większą kontrolę nad formatem wyjściowym., id=”aa8cfd3cbd”>
printf
nie tworzy nowej linii po każdym rekordzie, więc używamy \n
:
1. Bucks Milwaukee 60 22 0.732 2. Raptors Toronto 58 24 0.707 3. 76ers Philadelphia 51 31 0.622 4. Celtics Boston 49 33 0.598 5. Pacers Indiana 48 34 0.585
następujące polecenie oblicza sumę wartości przechowywanych w trzecie pole w każdej linii:
awk '{ sum += $3 } END { printf "%d\n", sum }' teams.txt
266
oto kolejny przykład pokazujący, jak używać wyrażeń i instrukcji sterujących do drukowania kwadratów liczb od 1 do 5:
awk 'BEGIN { i = 1; while (i < 6) { print "Square of", i, "is", i*i; ++i } }'
Square of 1 is 1Square of 2 is 4Square of 3 is 9Square of 4 is 16Square of 5 is 25
polecenia jednoliniowe, takie jak powyższe, są trudniejsze do zrozumienia i utrzymania., Przy pisaniu dłuższych programów należy utworzyć osobny plik programu:
BEGIN { i = 1 while (i < 6) { print "Square of", i, "is", i*i; ++i } }
uruchom program, przekazując nazwę pliku do interpretera awk
interpreter:
awk -f prg.awk
Możesz również uruchomić program awk jako program wykonywalny, używając dyrektywy shebang i ustawiając awk
interpreter:
#!/usr/bin/awk -fBEGIN { i = 1 while (i < 6) { print "Square of", i, "is", i*i; ++i } }
Zapisz plik i ustaw go jako wykonywalny :
chmod +x prg.awk
Możesz teraz uruchomić program wpisując:
./prg.awk
używając zmiennych powłoki w programach Awk #
Jeśli używasz polecenia awk
w skryptach powłoki, istnieje szansa, że będziesz musiał przekazać zmienną powłoki do programu AWK. Jedną z opcji jest załączenie programu podwójnym zamiast pojedynczych cudzysłowów i zastąpienie zmiennej w programie., Jednak ta opcja sprawi, że twój program awk będzie bardziej złożony, ponieważ będziesz musiał uciec od zmiennych awk.
zalecanym sposobem użycia zmiennych powłoki w programach awk jest przypisanie zmiennej powłoki do zmiennej awk. Oto przykład:
num=51
awk -v n="$num" 'BEGIN {print n}'