2009-05-29 54 views
2

是否有算法或diff-like工具来查找两个csv文件之间的差异? 实施例:如何找到csv记录的差异

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

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

利用这种差异状公用事业它将输出3种类型的记录:

  1. 记录,仅在文件1 (file1的减去file2的设定操作)
  2. 记录存在仅存在于文件2(文件2减文件1设置操作)
  3. 在文件1和文件2中存在的记录(相交集操作)
+0

不知道如果有一个,但只需要大约30分钟来写用Perl这样的工具:) – workmad3 2009-05-29 10:57:37

回答

6

diff可以做你想做的..

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

您可以在Perl中使用散列。阅读每个文件到一个单独的哈希值,像

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 

要打印出来的结果,就可以通过散列循环和检查键/值是相同的,不同的或以各种方式失踪。示例:

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

您可以使用unix'join'命令来执行此操作。它也适用于Windows的Cygwin。

例子:

$ 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

还有`comm`。 – Svante 2009-05-29 11:50:25

+0

尽管在CSV中有逗号,但两者都会中断。 – hbn 2009-05-29 11:53:48

0

你可以看看我的自由和开放源码的CSV流编辑器CSVfix,它不通过你的连接命令想要的东西 - 无需编程。

0

如何使用SQLite的例子吗?

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 
; 

这里是输出:

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

看看http://sourceforge.net/projects/csvdiff/

csvdiff是一个Perl脚本,DIFF /比较与 可能性来选择分离器2个的CSV文件。差异将显示如下: “记录999中的列XYZ”不同。在此之后,将显示此列的实际和预期结果。

1

开源DiffKit是能够做到这一点:

www.diffkit.org