2009-05-29 7 views
2

Gibt es einen Algorithmus oder Diff-ähnliche Dienstprogramme, um den Unterschied zwischen zwei CSV-Dateien zu finden? Beispiel:So finden Sie Unterschied in CSV-Datensatz

file1 
------- 
key1,value1 
key2,value2 
key3,value3 
key5,value5 
key7,value7 

file2 
------- 
key1,value1 
key3,value3 
key4,value4 
key5,value5 
key6,value6 

Mit diesem diff-like Dienstprogramme es Ausgang 3 Arten von Datensätzen:

  1. Datensätze, die (file2 eingestellten Betriebs file1 minus) in file1 existiert nur
  2. Datensätze, die nur existiert in file2 (file2 minus file1 Set-Operation)
  3. Datensätze, die beide in file1 und file2 existiert (set Betrieb schneiden)
+0

Sie wissen nicht, wenn es einen gibt, aber es dauert nur etwa 30 Minuten mit Perl ein solches Instrument zu schreiben :) – workmad3

Antwort

6

diff können tun, was Sie wollen ..

diff file1.csv file2.csv --old-line-format="< %L" --new-line-format="> %L" --unchanged-line-format="= %L" 
+0

Ich denke, das ist wirklich etwas, was ich verwenden könnte, in einem Befehl habe ich alle Unterschiede. – hendrasaputra

+0

Ich würde hinzufügen, dass Sie beide CSV-Dateien zuerst mit dem Befehl Sortieren sortieren sollten. Ich würde auch hinzufügen, dass nicht 100% zuverlässig ist, wenn Ihre CSV mehrzeilige Reihen hat, in welchem ​​Fall Sie die Datei richtig mit Text :: xSV analysieren müssten, die Schlüssel in Hashes aufzeichnen und sie mit List :: Util und vergleichen/oder Liste :: MoreUtil. – jiggy

0

Sie können Hashes in Perl verwenden. Lesen Sie jede Datei in einen separaten Hash, so etwas wie

my %File1 =(); 
my %File2 =(); 
# Filehandles FP1 and FP2 is opened for read 
while (<FP1>) { 
    if (/^([^,]+),(.+)$/) { 
     my ($key, $value) = ($1, $2); 
     $File1{$key} = $value; 
    } 
} 
# Repeat for FP2 

Um die Ergebnisse zu drucken, können Sie die Hashes Schleife durch und prüfen Sie, ob der Schlüssel/Wert identisch ist, anders oder auf verschiedene Weise fehlt. Beispiel:

for my $key (keys %File1) { 
    if (defined($File1{$key}) && defined($File2{$key}) { 
     print("$key exists in both files\n"); 
    } elsif (defined($File1{$key})) { 
     print("$key exists only in file1\n"); 
    } 
} 
# Repeat for %File2 
1

Sie können dazu den Unix-Befehl 'join' verwenden. Es ist auch in Cygwin für Windows verfügbar.

Beispiel:

$ join -t ',' -v 1 file1 file2 
key2,value2 
key7,value7 
$ join -t ',' -v 2 file1 file2 
key4,value4 
key6,value6 
$ join -t ',' file1 file2 
key1,value1,value1 
key3,value3,value3 
key5,value5,value5 
+2

Es gibt auch 'comm'. – Svante

+0

Beide brechen, wenn Sie in Ihrer CSV-Datei ein Komma in Anführungszeichen haben. – hbn

0

Sie einen Blick auf meine FOSS CSV Stream-Editor nehmen könnte CSVfix, das tut, was Sie über den Befehl anschließen möchten - keine Programmierung erforderlich.

0

Wie wäre es ein Beispiel SQLite mit? Hier

DROP TABLE 'file1'; 
DROP TABLE 'file2'; 

CREATE TABLE 'file1' (
    key_field VARCHAR primary key, 
    value_field VARCHAR 
); 

CREATE TABLE 'file2' (
    key_field VARCHAR primary key, 
    value field VARCHAR 
); 


.bail off 
.separator , 
.import file1.csv file1 
.import file2.csv file2 

.output stdout 
.header on 

SELECT col1 AS 'In file1.csv, not in file2.csv' FROM (
    SELECT file1.key_field AS col1, 
      file2.key_field AS col2 
    FROM file1 LEFT OUTER JOIN file2 
    ON file1.key_field == file2.key_field 
) 
WHERE col2 IS NULL 
; 

SELECT col2 AS 'In file2.csv, not in file1.csv'FROM (
    SELECT file1.key_field AS col1, 
      file2.key_field AS col2 
    FROM file2 LEFT OUTER JOIN file1 
    ON file2.key_field == file1.key_field 
) WHERE col1 IS NULL 
; 

SELECT file1.key_field AS 'In both file1.csv and file2.csv' 
    FROM file1 INNER JOIN file2 
    WHERE file1.key_field == file2.key_field 
; 

ist die Ausgabe:

C:\Temp> sqlite3 test.db < t.sql 
In file1.csv, not in file2.csv 
key2 
key7 
In file2.csv, not in file1.csv 
key4 
key6 
In both file1.csv and file2.csv 
key1 
key3 
key5 
2

Werfen Sie einen Blick auf http://sourceforge.net/projects/csvdiff/

csvdiff ist ein Perl-Skript zu diff/Vergleich von zwei CSV-Dateien mit der Möglichkeit, den Separator zu wählen . Unterschiede werden wie folgt angezeigt: "Spalte XYZ in Datensatz 999" ist anders. Danach werden das aktuelle und das erwartete Ergebnis für diese Spalte angezeigt.

1

Open Source DiffKit ist in der Lage, dies zu tun:

www.diffkit.org