Logo


Kurs programowania w Bash'u

Nowości       Porady       Księga      

AWK

AWK jest to język wyszukiwania wzorców oraz przetwarzania tekstów.
Wygląda to następująco:

awk '{przetwarzanie}'


Przydaje sie, kiedy chcemy wypisać tylko określone wiersze lub kolumny z pliku lub czytane z wyjścia jakiegoś polecenia.
AWK przetwarza plik wiersz po wierszu, zapisując dany wiersz i poszczególne kolumny w zmiennych. Brzmi to trochę skomplikowanie ale nie należy się przejmować - w rzeczywistości jest to bardzo proste. Już podaje przykład: Przypuśćmy że posiadamy plik Telefony z numerami telefonów w formacie:


Mariusz 233-34-35 Włocławek
Ania 223-22-33 Sopot


i chcemy wyświetlić tylko imiona i numery telefonów (miasto nas nie interesuje) to robimy następująco:

cat Telefony | awk'{print $1, $2}'


lub

awk'{print $1, $2}' < Telefony

Oba polecenia dają identyczne wyniki, pierwsze przekazuje (potokiem) plik wyświetlony poleceniem cat, drugie pobiera dane bezpośrednio z pliku.

Ne ekranie zobaczymy oczywiście:

Mariusz 233-34-35
Ania 223-22-33

Zatem wiadomo już że kolejne kolumny przechowywane są w zmiennych opatrzonych kolejnymi liczbami. Dokładnie tak jak poniżej.

$1 - pierwsza kolumna
$2 - druga kolumna
$3 - trzecia kolumna
....
$n - n-ta kolumna


$0 oznacza cały wiersz

W naszym przypadku będzie to wyglądało następująco:

$1="Mariusz"         $2="233-34-35"

a następnie:

$1="Ania"         $2="223-22-33 "


Oczywiście w zmiennej $0 będzie siedział cały pierwszy wiersz:

$0="Mariusz 233-34-35"

później

$0="Ania 223-22-33"

i tak w kółko aż do końca pliku - wygodne prawda?

Co zrobić jeśli chcemy zachować nasze wyniki w drugim pliku?

Oczywiście użyjemy znanego nam przekierowania >

Robimy to następująco:

cat Telefony | awk'{print $1, $2}' > Tel_bez_miast

lub

awk'{print $1, $2}' < Telefony > Tel_bez_miast

Teraz pokażę jak postępować z danymi pochodzącymi z poleceń wydawanych bezpośrednio z konsoli, chyba najpopularniejszą komendą jest ls. Użyje jej z parametrem -l aby dostać dużo informacji. Będziemy mogli sami zdecydować które kolumny mają być wyświetlone. :)

Przykładowy wydruk polecenia ls -l:

drwxrwxr-x 2 mariusz mariusz 1024 mar 31 20:48 Praca
-rw-r--r-- 1 mariusz mariusz 34304 mar 23 18:56 ~z_sieci


Przypuśćmy że chcemy wypisać tylko kolumny 1 oraz 9, czyli prawa dostępu do pliku oraz plik/katalog. Wystarczy do tego instrukcja:

ls -l | awk '{print $1,$9}'

Teraz nasz wydruk wygląda następująco:

drwxrwxr-x Praca
-rw-r--r-- ~z_sieci

Nic nie staje na przeszkodzie aby wyświetlić kolumny w odwrotnej kolejności:

ls -l | awk '{print $9,$1}'

Wynik:

Praca drwxrwxr-x
~z_sieci -rw-r--r--

Mając plik z danymi pracownika w formacie:

Imie Nazwisko Stanowisko Tel. domowy Miasto
Jan Kowalski Kierownik 233-22-21 Włocławek
Elwira Lewandowska Sekretarka 241-13-13 Toruń
Antoni Kwiatkowski Dyrektor 413-14-55 Włocławek

chcąc wypisać odpowiednio kolumny: Nazwisko, Imię, Tel. domowy, piszemy:

cat dane | awk '{print $2, $1, $4}'


Może zdarzyć się że separatorem kolumn będzie znak dwukropka:

Jan:Kowalski:Kierownik:233-22-21:Włocławek


Wtedy używamy parametru -Fseparator, w tym przypadku będzie to miało postać:

cat dane | awk -F: '{print $2, $1, $4}'

Jeśli życzymy sobie, aby kolumny na wyjściu były rozdzielone znakami tabulacji, albo dowolnym łancuchem możemy napisać:

cat dane | awk -F: '{print "Pierwsza kolumna: " $2,"druga:" $1,"trzecia:\t" $4}'

Wzorce z wyrażeniem regularnym


Przypuśćmy że chcemy wyświetlić wiersze zawierające wyraz TELEFON z pliku prywatne.txt:

awk '/TELEFON/' prywatne.txt


Możemy tutaj używać wszelkich wyrażeń regularnych jakie nam pzyjdą do głowy np:

awk '/TEL*/' prywatne.txt


awk '/^TELEFON/' prywatne.txt


awk '/[ao]la/' prywatne.txt


itp.

Mówiłem to o całych wierszach, jednak nic nie stoi na przeszkodzie aby sprawdzać poszczególne kolumny.



np polecenie ls -l wyświetla m.in. właściciela pliku oraz grupę do której należy:

drwxr-xr-x 2 root mariusz 1024 maj 9 19:13 publ.txt.txt
drwxr-xr-x 2 mariusz root 1024 maj 9 19:13 rower
-rwxrwxr-x 1 mariusz mariusz 45 kwi 9 22:08 rozmiar.txt

Nas interesuje tylko właściciel a więc piszemy:

ls -l | awk '$3 == "mariusz"'

Jeśli warunek spełniony, wiersz jest drukowany:

drwxr-xr-x 2 mariusz root 1024 maj 9 19:13 rower
-rwxrwxr-x 1 mariusz mariusz 45 kwi 9 22:08 rozmiar.txt

Utworzenie tabeli html z zawartości pliku. Plik ma dowolną ilość wierszy i jest w formacie:


a b c
d e f

Plik rozdzielamy na kolumny:

cat a | awk '{print $1,$2,$3}'

dodajemy instrukcje html'a (w cudzysłowach):

echo " < table border=1> " > tab.html

cat a | awk '{print "<tr><td>"$1"</td>", "<td>"$2"</td>", "<td>"$2"</td></tr>"}>> tab.html

echo "</table>">> tab.html

Dobra wiadomość: W AWK możemy dodać informacje, które mają się pojawić przed przetworzeniem pierwszego wiersza pliku (BEGIN), jak również po przetworzeniu ostatniego wiersza pliku (END):

Konstrukcja jest następująca:

awk 'BEGIN{nagłówek} {właściwe przetwarzanie} END{zakończenie}'


Po wykonaniu następujących instrukcji:

cat a | awk 'BEGIN{print "<table border=1>"}{print "<tr><td>"$1"</td>","<td>"$2"</td>","<td>"$3"</td></tr>"} END{print "</table>"}' >tab.html

w pliku tab.html pojawi się tekst:

<table border=1>
<tr><td>a</td><td>b</td> <td>c</td></tr>
<tr><td>d</td> <td>e</td> <td>f</td></tr>
</table>

Ostatnio dodano

O stronie

Stronę najlepiej oglądać w rozdzielczości 1024x768. Strona optymalizowana dla przeglądarki Mozilla.

Prośba

Jeśli chciałbyś coś zmienić lub uważasz że czegoś brakuje pisz. Odpiszę na każdy list.

Subskrypcja

Jeśli chcesz być informowany o nowościach na stronie wpisz tu swój e-mail i kliknij Wyślij.

O mnie

O autorze
Autorem kursu jest Mariusz Majerowski
Ostatnia aktualizacja: 23 VI 2004.