2017-02-10 5 views
1

Ich habe zwei Dateien, Datei1 und Datei2. Ich möchte mehrere Spalten vergleichen - $ 1, $ 2, $ 3 und $ 4 von Datei1 mit mehreren Spalten $ 1, $ 2, $ 3 und $ 4 von Datei2 und die Zeilen von Datei2 drucken, die keiner Zeile in Datei1 entsprechen.Spalten aus verschiedenen Dateien vergleichen und drucken, die nicht übereinstimmen

z.

file1

aaa bbb ccc 1 2 3 
aaa ccc eee 4 5 6 
fff sss sss 7 8 9 

file2

aaa bbb ccc 1 f a 
mmm nnn ooo 1 d e 
aaa ccc eee 4 a b 
ppp qqq rrr 4 e a 
sss ttt uuu 7 m n 
fff sss sss 7 5 6 

Ich möchte als Ausgabe haben:

mmm nnn ooo 1 d e 
ppp qqq rrr 4 e a 
sss ttt uuu 7 m n 

Ich habe für die Suche nach jenen Fragen hier zu sehen, dass Spiel zu tun und drucken, aber nicht umgekehrt, die nicht übereinstimmen.

Vielen Dank!

Antwort

2

Verwenden Sie das folgende Skript:

awk '{k=$1 FS $2 FS $3 FS $4} NR==FNR{a[k]; next} !(k in a)' file1 file2 

k ist der verketteten Wert der Spalt 1, 2, 3 und 4, begrenzt durch FS (siehe comments) und wird als ein Schlüssel bei der Suche verwendet werden Array a später. NR==FNR ist true beim Lesen file1. Ich erstelle das Array a indiziert von k beim Lesen file1.

Für die restlichen Zeilen des Eingangs überprüfe ich mit !(k in a), wenn der Index in a nicht existiert. Wenn dies trueawk ergibt, wird diese Zeile gedruckt.

+1

Invert der Bedingung, Katarina will „nicht in einem“ –

+0

Danke für die Erklärung, es funktioniert jetzt zu verwenden ist! –

+0

Sie sind willkommen – hek2mgl

1

Kein Zweifel, dass die awk Lösung von @ hek2mgl als dieses besser ist, aber für Informationen ist dies auch möglich, mit uniq, sort und rev:

rev file1 file2 | sort -k3 | uniq -u -f2 | rev 

rev wird beide Dateien von rechts zurückkehrt nach links .

sort -k3 ist Sortierzeilen überspringen die 2 erste Spalte.

uniq -u -f2 druckt nur Zeilen, die eindeutig sind (die 2 beim Vergleich zuerst auslassen).

Endlich kehrt die rev die Zeilen zurück.

Diese Lösung sortiert die Zeilen beider Dateien. Das könnte erwünscht sein oder nicht.

2

Hier ist ein weiterer Ansatz, wenn die Dateien sortiert sind und Sie den verwendeten Zeichensatz kennen.

$ function f(){ sed 's/ /~/g;s/~/ /4g' $1; }; join -v2 <(f file1) <(f file2) | 
    sed 's/~/ /g' 

mmm nnn ooo 1 d e 
aaa ccc eee 4 a b 
ppp qqq rrr 4 e a 
sss ttt uuu 7 m n 
fff sss sss 7 5 6 

ein Schlüsselfeld erstellen, indem erste vier Felder verketten (mit einem ~ char, aber nicht verwendete Zeichen verwendet werden können), verwenden join die nicht ausgeglichenen Einträge aus Datei2 und verteile das synthetische Schlüsselfeld zurück zu finden.

Allerdings ist die beste Art und Weise awk Lösung mit einem leichten fix

$ awk 'NR==FNR{a[$1,$2,$3,$4]; next} !(($1,$2,$3,$4) in a)' file1 file2 
Verwandte Themen