使用 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]]); },
});
我正在使用在批处理文件中调用的 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]]); },
});