====== 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