找到2个csv文件差异的有效方法

时间:2016-10-22 19:00:55

标签: java csv awk

我有两个大的(比如300,000 * 100)矩形csv文件,它们具有相同数量的相应行和列。我需要找到2个文件中每个相应单元格之间的差异。 程序应该o / p不同的行和单元格号以及不同的内容。

由于行数/列数非常大,我正在寻找最有效的方法。

最初我开始使用awk进行探索,而this看起来很有希望,但我之前没有使用过awk并且没有成功将其扩展到100列而不是2,如示例中所示

接下来,我尝试了一种使用Java的强力方法 - 将文件加载到2个2-D阵列中。初始化100个线程,每个线程在给定列上工作,当找到差异时,每个线程将行,单元格和diff值放入HashMap(列号为Key)。我确实尝试通过比较同时将第二个文件读入数组来进行优化,但实际上因为我正在访问每个单元格,所以没有办法可以很快(完成比较需要近8个小时)

我对awk或Java都没关系。并且对任何其他完全不同的方法开放。

3 个答案:

答案 0 :(得分:3)

awk救援!

awk

中执行此操作是明智的选择
$ paste -d, file.1 file.2 | 
  awk -F, '{m=NF/2; for(i=1;i<=m;i++) if($i!=$(i+m)) print NR,i,$i,$(i+m)}'

打印&#34;行#列#left right&#34;不等的细胞的价值。

如果除了行号之外还要打印键列,可以轻松添加

$ paste -d, file.1 file.2 | 
  awk -F, -v key=8 '{m=NF/2; 
                     for(i=1;i<=m;i++) 
                       if($i!=$(i+m)) print $key,NR,i,$i,$(i+m)}'

答案 1 :(得分:1)

需要考虑的事项:

$ cat file1
1,2,aa
1,2,3
1,bb,3
1,2,3

$ cat file2
1,2,cc
1,2,3
1,dd,3
1,2,3

$ diff file1 file2 |
awk -F, '
    /^[0-9]/ { row=$0+0; next }
    sub(/^< /,"") { split($0,a); next }
    sub(/^> /,"") { for (col=1;col<=NF;col++) if ($col != a[col]) print row, col, a[col], $col }
'
1 3 aa cc
3 2 bb dd

这应该非常快,因为它只执行awk并在有差异的行上进行循环,而不是所有行。

答案 2 :(得分:1)

univocity-parsers'CSV解析器处理时间不会超过5秒:

public void diff(File leftInput, File rightInput) {
    CsvParserSettings settings = new CsvParserSettings(); //many config options here, check the tutorial

    CsvParser leftParser = new CsvParser(settings);
    CsvParser rightParser = new CsvParser(settings);

    leftParser.beginParsing(leftInput);
    rightParser.beginParsing(rightInput);

    String[] left;
    String[] right;

    int row = 0;
    while ((left = leftParser.parseNext()) != null && (right = rightParser.parseNext()) != null) {
        row++;
        if (!Arrays.equals(left, right)) {
            System.out.println(row + ":\t" + Arrays.toString(left) + " != " + Arrays.toString(right));
        }
    }

    leftParser.stopParsing();
    rightParser.stopParsing();
}

披露:我是这个图书馆的作者。它是开源和免费的(Apache V2.0许可证)。