====== awk ====== Das supermächtige Tool **awk**: * Beispiel 1: **2 Dateien mergen**: Erste Datei: /home/user123/test001/ cat datei_1.unl 111|1234567|0|2005-10-25|1963-11-16| 111|2345678|0|2006-03-27|1990-04-21| 111|3456789|4|2005-09-26|1963-06-04| 111|4567890|0|2005-09-26|1979-08-07| 222|5678901|0|2005-09-26|1973-02-18| 222|6789012|1|2005-09-26|1950-01-01| 222|7890123|0|2006-03-27|1953-08-23| 222|8901234|0|2005-09-26|1972-04-13| 222|9012345|3|2005-09-26|1971-03-15| 333|0123456|0|2005-09-26|1950-01-01| Zweite Datei: /home/user123/test001/ head datei_2.txt A|200|1000004|5|20019||0|0| B|200|1001000|5|20019||0|0| C|200|1003009|5|20019||0|0| D|200|1004003|5|20019||0|0| E|200|1006000|5|20019||0|0| F|200|1007006|5|20019||0|0| G|200|1008006|7|20019||0|0| H|200|1009003|5|20019||0|0| I|200|1011004|4|20019||0|0| J|200|1012000|5|20019||0|0| Die 1. Datei wird in ein Array geladen (Teil "if (NR == FNR)"). Die Variable **NR** ist die über alle Files **übergreifende** laufende Zeilennummer. Die Variable **FNR** ist die laufende Zeilennummer innerhalb des **aktuell gelesenen** Files. Solange sie gleich sind, befindet sich das Skript innnerhalb der ersten Datei. awk -F"|" '{ if (NR == FNR) { zaehler = $3 anmeldedatum = $4 geburtsdatum = $5 if (zaehler >= 4) aktiv_kz = "R" else aktiv_kz = "-" grp_kennung = $1 $2 arr_gk[grp_kennung] = aktiv_kz FS anmeldedatum FS geburtsdatum next } grp_kennung = $2 $3 print $0 arr_gk[grp_kennung] }' datei_1.unl datei_2.txt :!: Wichtig dabei ist, daß beide Quell-Dateien nicht unbedingt identisch aufgebaut werden müssen, weil sie im Skript auf unterschiedliche Weise und unabhängig von einander (durch den Teil "if (NR == FNR)") behandelt werden. ---- * Beispiel 2: **Eine Spalte aus mehreren Files extrahieren**: __Aufgabe:__\\ Es gibt eine Menge von Logfiles, deren Inhalt eine Spalten-Struktur hat. Zum Beispiel, aus den Logfiles von dem WebServer aus dem Jahr 2010 soll (nur) die Spalte mit den IP-Adressen in eine separate Datei aufsteigend sortiert (ohne Dubletten) extrahiert werden. __Wir nehmen an:__\\ Die Log-Files heißen nach dem Muster "log-<6-stellige Nummer>.JJJJ-MM-TT".\\ Die IP-Adressen stehen in der Position 25 (beginnt mit 1) und haben die Länge von 15 Zeichen. for i in log-??????.2010-??-??; do cat $i | nawk '{printf("%s\n", substr($0, 25, 15));}' done | sort -u Sollen die Files bereits mit gzip komprimiert worden sein - kein Problem: for i in log-??????.2010-??-??.gz; do gzcat $i | nawk '{printf("%s\n", substr($0, 25, 15));}' done | sort -u ---- Stand: 17.11.2011 EOF