2017-09-12 2 views
0

Ich versuche alle Zeilen aus Datei eins + Spalte 3 aus Datei zwei zu drucken, wenn Spalte eins in beiden Dateien übereinstimmt, Spalte 3 jedoch nicht.AWK Vergleiche 2 Spalten in 2 Dateien, drucke, wenn eine gleich ist, andere nicht

Beispiel:

File1 
John 12 Mango 
David 13 Apple 
Jack 14 Orange 

File2 
John 12 Grape 
David 13 Apple 
Jack 14 Apple 

Ausgabe

John 12 Mango Grape 
Jack 14 Orange Apple 

Ich habe versucht, verschiedene awk-Befehle, aber sie funktionieren, wenn beide Spalte Matches, aber ich brauche zu drucken, wenn nur 1 Spalte Spiel und andere nicht. Ich bin ziemlich neu in Skript und Unix-Befehl, ich würde mich über eine kleine Erklärung der vorgeschlagenen Lösung freuen.

Antwort

1
$ awk 'NR==FNR{a[$1]=$3; next} ($1 in a) && (a[$1] != $3){print $0, a[$1]}' file2 file1 
John 12 Mango Grape 
Jack 14 Orange Apple 
+1

Das ist genau das, was ich gesucht habe, der Rest der Lösungen funktioniert auch, aber dies ermöglicht eine einfachere Modifikation. Ed, würdest du in der Lage sein, einen Überblick über deine Syntax zu geben und/oder ein Tutorial für die gleiche Verwendung von AWK vorschlagen? –

+0

erstellt eine Array-Zuordnung von $ 1 bis $ 3 beim Lesen von Datei2, dann wenn $ 1 von Datei1 ist ein Index in diesem Array vergleicht die $ 3 für die aktuelle $ 1 mit der $ 3 im Array durch den gleichen Index, wenn es von Datei2 gelesen wurde. Wenn der aktuelle $ 1 von Datei1 ein $ 1 in Datei2 und der $ 3 Wert von Datei1 nicht der gleiche wie der $ 3 Wert von Datei 1 ist, dann druckt er die aktuelle Zeile von Datei1, gefolgt von $ 3 von Datei2, indiziert von $ 1. Hoffnung, die Sinn macht. Holen Sie sich das Buch Effective Awk Programming, 4. Auflage, von Arnold RObbins, –

0

awk Lösung:

$ cat tst.awk 
NR==FNR { a[$1" "$2]=$3; next } 
{ s=$1" "$2; 
    if (s in a && a[s] != $3) 
    printf("%s %s %s\n", s, a[s], $3) 
} 

Running:

$ awk -f tst.awk input1.txt input2.txt 
John 12 Mango Grape 
Jack 14 Orange Apple 

EDIT generische Version: Spiel Spalte 1 und Mismatch in der Spalte col

$ cat tst2.awk 
BEGIN {col=3} 
NR==FNR { a[$1]=$0; next } 
$1 in a { 
    split(a[$1],b," "); 
    if ($col!=b[col]) 
     print a[$1], $col 
} 

Sie könnten sogar löschen die BEGIN aus der awk-Datei und fügen Sie die Variable col Kommandozeile, wie folgt aus:

$ awk -v col=3 -f tst2.awk input1.txt input2.txt 
John 12 Mango Grape 
Jack 14 Orange Apple 
+0

Danke für die Antwort Marc. Aber gibt es einen Weg, dass ich nur Spalte eins spezifisch zusammenbringen könnte und in Spalte 3 missmatch? unabhängig von der 2. Spalte. Der Grund, den ich gefragt habe, hängt von der Situation ab, die ich brauche, um die Spalte für Match und Missmatch zu ändern, und in Zukunft könnte ich zusätzliche Spalten bis zu insgesamt 6 haben. –

+0

Eine allgemeinere Version hinzugefügt, um zu antworten. –

0

Paste + awk Ansatz:

paste <(sort file1) <(sort file2) | awk '$1==$4 && $3!=$6{ print $1,$2,$3,$6 }' 

Der Ausgang:

Jack 14 Orange Apple 
John 12 Mango Grape 
+0

Das ist eine interessante Lösung, aber ich denke, es wird begrenzt sein, wenn die eine Datei zusätzliche Zeilen hat und einen Offset für den Rest der Datensätze verursachen wird. –

0

Wenn Sie eine generische Lösung benötigen, folgen Sie ing einen einfachen Perl-Skript (~ 30 Zeilen), sollte es für die beliebige Anzahl von Spalten in Dateien arbeiten und angepasst/mismatched Spaltennummern als Eingangsparameter gegeben -

use strict; 

my @f1; my @f2; 

open F, config()->{file1} or die $!; 
while (<F>){ 
    chomp; 
    next unless /\S+/; 
    push @f1, [ split /\s+/ ]; 
} 
close F; 

open F, config()->{file2} or die $!; 
while (<F>){ 
    chomp; 
    next unless /\S+/; 
    push @f2, [ split /\s+/ ]; 
} 
close F; 

my $c1 = config()->{'match_col_num'}-1; 
my $c2 = config()->{'mismatch_col_num'}-1; 

for my $l1 (@f1){ 
    for my $l2 (@f2){ 
    if ($l1->[$c1] eq $l2->[$c1] and $l1->[$c2] ne $l2->[$c2]){ 
     print join " ", (@{$l1}, $l2->[$c2]); 
     print "\n"; 
    } 
    } 
} 

Benutzungs- Information sehen auf https://github.com/melezhik/file-compare-columns

Verwandte Themen