使用 Perl 比较 2 个大文件

Using Perl to compare 2 large files

我正在使用在批处理文件中调用的 Perl 比较 2 个大型 CSV 文件。 我把结果放在第三个文件中。

当前文件包含其他信息,例如 headers,以及其他行,例如:

--- file1.txt   Wed Mar  7 14:57:10 2018
+++ file2.txt   Wed Mar  7 13:56:51 2018
@@ -85217,4 +85217,8 @@

结果文件怎么可能只包含差异? 谢谢。

这是我的 perl:

#!/usr/bin/env perl
use strict; use warnings;
use Text::Diff;
my $diffs = diff 'file1.txt' => 'file2.txt';
print $diffs;

这是我的批处理文件:

perl diffperl.pl > newperl.csv

您应该查看 the documentation for Text::Diff 中的 STYLE 选项。 built-in 样式中的一种可能更符合您的喜好。但如果不是这种情况,您可以编写自己的格式化包。在我看来你只需要提供一个 hunk_header() 方法 returns 一个空字符串(因为它是你不喜欢的大块 header 行)。

统一格式,

  • 前两行表示正在比较的文件。
  • 以“@”开头的行表示文件中差异的位置。
  • 以“-”开头的行表示仅在第一个文件中的行。
  • 以“+”开头的行表示仅在第二个文件中的行。
  • 以 space 开头的行表示两个文件中都有的行。
  • 输出可能包含行“\ No newline at end of file”。
  • 差异中的每一行都将是 newline-terminated,即使输入的行不是。

解决方案:

$diffs =~ s/^(?:[^\n]*+\n){2}//;
$diffs =~ s/^[\@ \][^\n]*+\n//mg;

请注意,添加 CONTEXT => 0 会减少要删除的行数。


也就是说,直接使用 Text::Diff if you want your own output format. You might as well use Algorithm::Diff 没有多大意义。

use Algorithm::Diff qw( traverse_sequences );

my $qfn1 = 'file1.txt';
my $qfn2 = 'file2.txt';

my @file1 = do { open(my $fh, '<', $qfn1) or die("Can't open \"$qfn1\": $!\n"); <$fh> };
my @file2 = do { open(my $fh, '<', $qfn2) or die("Can't open \"$qfn2\": $!\n"); <$fh> };

if (@lines1) { chomp($lines1[-1]); $lines1[-1] .= "\n"; }
if (@lines2) { chomp($lines2[-1]); $lines2[-1] .= "\n"; }

traverse_sequences(\@lines1, \@lines2, {
   DISCARD_A => sub { print("-", $lines1[$_[0]]); },
   DISCARD_B => sub { print("+", $lines2[$_[1]]); },
});