2013-02-25 8 views
8

Hallo Ich habe zwei ähnliche Dateien (beide mit 3 Spalten). Ich würde gerne überprüfen, ob diese beiden Dateien die gleichen Elemente enthalten (aber in einer anderen Reihenfolge aufgeführt). nur die ersten Spalten Zunächst einmal würde ichDateien mit awk vergleichen

file1.txt

"aba" 0 0 
"abc" 0 1 
"abd" 1 1 
"xxx" 0 0 

file2.txt

"xyz" 0 0 
"aba" 0 0 
"xxx" 0 0 
"abc" 1 1 

vergleichen wollen Wie kann ich es tun mit awk? Ich habe versucht, mich umzusehen, aber ich habe nur komplizierte Beispiele gefunden. Was, wenn ich auch die anderen beiden Spalten zum Vergleich hinzufügen möchte? Die Ausgabe sollte mir die Anzahl der übereinstimmenden Elemente geben.

+0

http://theunixshell.blogspot.in/2012/12/i-have-two-files-file-1-conta ins-3.html – Vijay

Antwort

25

Um die gemeinsamen Elemente in beiden Dateien zu drucken:

$ awk 'NR==FNR{a[$1];next}$1 in a{print $1}' file1 file2 
"aba" 
"abc" 
"xxx" 

Erläuterung:

NR und FNR sind awk Variablen, die die Gesamtzahl der Datensätze und die Anzahl der Datensätze in der aktuellen Dateien speichern bzw. (der Standard-Datensatz ist eine Zeile).

NR==FNR # Only true when in the first file 
{ 
    a[$1] # Build associative array on the first column of the file 
    next # Skip all proceeding blocks and process next line 
} 
($1 in a) # Check in the value in column one of the second files is in the array 
{ 
    # If so print it 
    print $1 
} 

Wenn Sie die ganze Linien passen wollen, dann verwenden $0:

$ awk 'NR==FNR{a[$0];next}$0 in a{print $0}' file1 file2 
"aba" 0 0 
"xxx" 0 0 

oder einen bestimmten Satz von Spalten:

$ awk 'NR==FNR{a[$1,$2,$3];next}($1,$2,$3) in a{print $1,$2,$3}' file1 file2 
"aba" 0 0 
"xxx" 0 0 
+0

Speziell wegen der Erklärung des Awk-Skripts gewählt, danke! – vfilby

+0

@iiSeymour Wie wird die zweite Datei von Datei1 gedruckt, wenn die erste Datei von Datei2 im assoziativen Array gefunden wurde? –

6

die Anzahl der passenden Elemente zu drucken, ist hier ein Weg mit awk:

awk 'FNR==NR { a[$1]; next } $1 in a { c++ } END { print c }' file1.txt file2.txt 

Ergebnisse Ihre Eingabe mit:

3 

Wenn Sie zusätzliche Spalten möchte hinzufügen (zum Beispiel Spalten ein, zwei und drei), verwenden Sie ein pseudo-multidimensional array:

awk 'FNR==NR { a[$1,$2,$3]; next } ($1,$2,$3) in a { c++ } END { print c }' file1.txt file2.txt 

Ergebnisse mit Ihrer Eingabe:

2 
+0

+1. Da die Dateien von OP nur 3 Spalten haben, ist es besser, wenn Sie 'a [$ 0]' anstelle von 'a [$ 1, $ 2, $ 3]' verwenden. Dann können alle nicht übereinstimmenden unsichtbaren Leerzeichen in einer der beiden Dateien zu einer unerwarteten Ausgabe führen. Vielleicht benutze rtrim oder gsub dafür. –

+1

Verwendet es so -> za $ awk 'FNR == NR {a [$ 1]; next}! ($ 1 in a) ENDE {print $ 1} 'test.csv test2.csv zum Drucken der nicht übereinstimmenden Datensätze. – zee

+0

@zee: Danke für die Abstimmung, aber du brauchst deinen 'END'-Block nicht – Steve