Wstęp
Nie zamierzam przedstawiać tu pełnego opisu języka awk. Autorami jego są Alfreda V. Aho1, Petera Weinberger i Brian Kernighan2. Jest to bardzo sympatyczny język pomocny podczas przetwarzania danych o ustalonej strukturze. Nie wymaga kompilacji programów, składnia w bardzo wielu miejscach jest identyczna ze składnią języka C. Występuje kilka „smaków” tego języka: awk, mawk i gawk.
Zasada przetwarzania
Zasada działania języka jest bardzo prosta: każda linia kodu składa się z dwu części:
- „wyzwalacza”,
- „akcji”.
Wejściowy plik lub strumień danych (który składa się z szeregu rekordów podzielonych na pola) czytany jest rekord po rekordzie. Każdy rekord porównywany jest z „wyzwalaczem”. Jeżeli występuje zgodność (na przykład gdziekolwiek w rekordzie jest ciąg znaków zgodny z wyrażeniem regularnym zapisanym w wyzwalaczu) — uruchamiane są polecenia opisane w „akcji”. W szczególności może nie być wyzwalacza. Wówczas polecenia akcji wykonywane są dla każdego rekordu. Specjalne polecenie next pozwala przerwać przetwarzanie i przejść do analizy następnego rekordu.
W szczególności program
1 |
/A/ {print $0} |
wydrukuje wszystkie rekordy w których wystąpi gdziekolwiek litera „A”.
Rekordy i pola
Każda linia tekstu jest rekordem. Można odwoływać się do jej zawartości przez symbol $0.
Zakłada się, że każdy rekord składa się z kilku pól oddzielonych jakimś znakiem. Standardowo znakiem tym jest odstęp (ale można go zmienić). Zatem rekord:
1 |
Ala ma kota |
składa się z trzech pól. Do pierwszego z nich odwołujemy się przez symbol $1, drugiego $2 i tak dalej.
Przykładowe dane
W naszym przypadku przykładowe dane wyglądają tak:
1 2 3 4 5 6 7 8 9 10 11 12 |
--- AVERAGE 300 2015-10-05 00:15:00 CEST , 1443996900 , 1.5949831725e+01 2015-10-05 00:20:00 CEST , 1443997200 , 1.5913256599e+01 ... --- AVERAGE 1800 2015-09-29 00:30:00 CEST , 1443479400 , 1.1161724973e+01 2015-09-29 01:00:00 CEST , 1443481200 , 1.1743634838e+01 ... --- AVERAGE 86400 2014-10-06 02:00:00 CEST , 1412553600 , NaN 2014-10-07 02:00:00 CEST , 1412640000 , NaN ... |
(w miejscu kropeczek jest więcej wartości). Oprócz danych uśrednionych są również wartości minimalne (MIN) i maksymalne (MAX).
Liczba (300, 1800. 86400,…) mówi o okresie uśredniania (w sekundach). Do analizy należy brać tylko jeden z bloków danych. zaprezentowany program w awk „tnie dane” w tych miejscach gdzie pojawi się linia zaczynająca się od trzech minusów, a resztę napisu traktuje jako nazwę pliku do którego dane zostaną zapisane.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# <- to jest znak komentarza ; (średnik) to koniec polecenia # każda linia programu w awk skłąda się z dwu części: # „wyzwalacza” (pierwsza część oraz jednego lub więcej # poleceń zgrupowanych w nawiasach klamrowych. # BEGIN to specjalny wyzwalacz — polecenia wykonywane # są na początku programu. W innych przypadkach # wyzwalacz to wyrażenie regularne. # Jeżeli rekord wejściowy zgodny jest z wyrażeniem — # polecenia są wykonywane BEGIN {FS=","} # definiuję separator pól jako przecinek # (standardowo odstęp) /^---/ {gsub("---", ""); gsub(" ",""); filename=$0; print filename; next} # Powyższe polecenie znaczy tyle, że dla każdej linii, która # zaczyna się od znaków --- (^ oznacza, że ma to być na początku # linii) należy wykonać grupę poleceń w nawiasach klamrowych. # Polecenie next na końcu oznacza, że należy przejść do następnego # rekordu wejściowego. Funkcja gsub zamienia wszystkie znaki będące # pierwszym jej argumentem na argument drugi, w rekordzie # wejściowym. Cały rekord wejściowy to $0, a $1, $2,… # to kolejne pola (oddzielone znakiem FS) rekordu { print $2, $3 >> filename } # powyższa grupa poleceń nie ma wyzwalacza — wykonywana # jest dla każdego rekordu wejściowego. # rekordy wejściowe z pliku csv mają postać: # 2015-10-10 01:40:00 CEST , 1444434000 , 8.7317967344e-01 # data w postaci czytelnej to $1, unix timestamp to $2, a zmierzona # wartość to $3 jedynie drugie i trzecie pole dopisywane jest (>>) # do pliku o nazwie zawartej w zmiennej # filename |
Plik do pobrania. Klikamy prawym klawiszem myszy i zapisz jako cut.awk
.
Użycie
W terminalu wydajemy polecenie:
1 |
awk -f cut.awk temperatura_06102015_0010.csv |
w kartotece powstaną pliki o nazwach: AVERAGE300, itd.