如何使用Perl来确定两个文件的内容是否相同?

时间:2010-05-17 09:30:55

标签: perl file comparison

这个问题来自于需要确保我对代码所做的更改不会影响它输出到文本文件的值。理想情况下,我会滚动一个子以接收两个文件名return 1return 0,具体取决于内容是否相同,空格和所有内容。

鉴于文本处理是Perl的强项,比较两个文件并确定它们是否相同(未经测试的代码)应该很容易。

use strict;
use warnings;

sub files_match {

    my ( $fileA, $fileB ) = @_;
    open my $file1, '<', $fileA;
    open my $file2, '<', $fileB;

    while (my $lineA = <$file1>) {

        next if $lineA eq <$file2>;
        return 0 and last;
    }

    return 1;
}

我能想到的唯一方法(没有CPAN模块)是打开有问题的两个文件,并逐行读取它们,直到找到差异为止。如果没有找到差异,则文件必须相同。

但这种做法有限且笨拙。如果两个文件中的总行数不同怎么办?我应该打开和关闭以确定行数,然后重新打开以扫描文本?呸。

我在perlfaq5中没有看到与此相关的任何内容。我希望远离模块,除非它们带有核心Perl 5.6.1发行版。

2 个答案:

答案 0 :(得分:30)

它位于core

use File::Compare;

if (compare("file1", "file2") == 0) {
  print "They're equal\n";
}

答案 1 :(得分:7)

您可以先进行几次O(1)检查,看看文件是否不同。

如果文件大小不同,那么它们显然是不同的。 stat函数将返回文件的大小。它还将返回另一段有用的数据:inode编号。如果这两个文件实际上是同一个文件(因为两个文件都传递了相同的文件名,或者两个名称都是同一文件的硬链接),则inode编号将相同。文件显然与其本身相同。除了这两个检查之外,没有更好的方法来比较两个本地文件的等价性,而不是直接将它们相互比较。当然,没有必要逐行进行,如果您愿意,可以阅读更大的块。

#!/usr/bin/perl

use strict;
use warnings;

use File::Compare ();

sub compare {
    my ($first, $second)             = @_;
    my ($first_inode, $first_size)   = (stat $first)[1, 7];
    my ($second_inode, $second_size) = (stat $second)[1, 7];

    #same file, so must be the same;
    return 0 if $first_inode == $second_inode;

    #different sizes, so must be different
    return 1 unless $first_size == $second_size;

    return File::Compare::compare @_;
}

print compare(@ARGV) ? "not the " : "", "same\n";