2009-05-29 3 views
2

2つのcsvファイルの違いを見つけるためのアルゴリズムまたはdiffのようなユーティリティはありますか? 例:この差分のようなユーティリティで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. のみFILE1 (FILE1マイナスFILE2セット動作)
  2. レコードに存在するレコードのみファイル2に存在する(ファイル2からファイル1のセット操作)
  3. ファイル1とファイル2の両方に存在するレコード(交差設定操作)
+0

は分からないのですが、それは唯一のperlで、このようなツールを書くのに約30分かかります:) – workmad3

答えて

6

diffは..あなたが望むものSQLiteを使用する例について

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

これは本当に私が使うことができるものだと思います。あるコマンドではすべての違いがあります。 – hendrasaputra

+0

sortコマンドを使用してCSVファイルの両方を最初にソートする必要があることを追加します。あなたのCSVに複数行の行がある場合、Text :: xSVでファイルを正しく解析し、キーをハッシュに記録してList :: Utilと比較する必要がある場合は、100%信頼できないとも付け加えます。 /またはList :: MoreUtil。 – jiggy

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'コマンドを使用してこれを行うことができます。これはCygwin for Windowsでも利用可能です。

例:

$ 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

+0

あなたのCSVに引用符をつけても、両方が壊れてしまいます。 – hbn

0

あなたはjoinコマンドを経由して何をしたいん私のFOSS CSVストリームエディタCSVfix、見てかかることがあります - 必要なプログラミングなしに。

0

方法を行うことができますか?ここで

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は差分に/セパレーターを選択するために 可能性を持つ2つのCSVファイルを比較するPerlスクリプトです見てみましょう。差異は次のように表示されます。 "レコードXYZのレコード999"は異なります。その後、この列の実際の結果と の予想結果が表示されます。

1

オープンソースDiffKitはこれを行うことができるである:1がある場合

www.diffkit.org

関連する問題