jmop

Einen Moment…

jmop header image 2

awk – Dateien vergleichen

Januar 23rd, 2008 · No Comments

awk und seine assoziativen Arrays sind sehr mächtig – insbesondere, wenn man sie versteht. Kürzlich bin ich über

awk 'NR==FNR { ++a[$0]; next } !a[$0] ' <datei1> <datei2>

gestolpert und hatte verstanden, dass ich zwei Dateien daraufhin untersuchen kann, ob die Werte aus der einen Datei auch in der anderen enthalten sind. Genauer gesagt: diejenigen Zeilen aus <datei2>, die nicht in <datei1> vorkommen, werden ausgegeben.

Ganz verstanden hatte ich das nicht, bis ich einen Kollegen gefragt hatte, der sich mit awk gut auskennt (danke, Mathias!).

Die Bedingung NR==FNR trifft nur auf die erste Datei zu, da
NR die (Gesamt-)Zahl der bisher gelesenen records (Zeilen) enthält und
FNR die Zahl der gelesenen records (oder Zeilen) der aktuellen Datei.

Die Gleichheit ist nur bei der ersten Datei gegeben – bei der zweiten aber nicht mehr. Das Schöne an den assoziativen Arrays ist nun, dass man die Daten der ersten Datei beliebig zwischenspeichern kann – vorausgesetzt, es gibt einen Schlüssel für den Array, der eindeutig ist. Hat man also zwei Dateien, bei denen man einen gemeinsamen Schlüssel hat, kann man hiermit Vergleiche durchführen. Dazu ein Beispiel:

Inhalt <datei1>
4711;hugo
4712;egon
4713;bert

Inhalt <datei2>
4712;willi
4711;hugo
4713;bert
4714;bert

Wenn ich nun wissen will, ob die Zuordnung der ID (also der Zahl) zum Namen, in beiden Dateien identisch ist (oder nicht), genügt folgendes Skript (man bedenke aber die Folge des Vertauschens der beiden zusätzlichen Dateien(!) – das Ergebnis sieht dann nämlich anders aus):

BEGIN { FS=";" }
NR==FNR { a[$1]=$0; next }
($1 in a) {
   split(a[$1], tmpArr, ";")
   if ($2 == tmpArr[2]) {
      printf "Wert für Schlüssel [%s] identisch: %s\n", $1, $2
   }
}
!($1 in a ) { printf "Schlüssel [%s] nicht gefunden!\n", $1 }

und produziert die Ausgabe:

Wert für Schlüssel [4711] identisch: hugo
Wert für Schlüssel [4713] identisch: bert
Schlüssel [4714] nicht gefunden!

Tags: awk

0 responses so far ↓

  • There are no comments yet...Kick things off by filling out the form below.

Leave a Comment