如何使用 Perl 判断两个文件的内容是不是相同?
Posted
技术标签:
【中文标题】如何使用 Perl 判断两个文件的内容是不是相同?【英文标题】:How can I use Perl to determine whether the contents of two files are identical?如何使用 Perl 判断两个文件的内容是否相同? 【发布时间】:2011-02-20 07:59:29 【问题描述】:这个问题来自于需要确保我对代码所做的更改不会影响它输出到文本文件的值。理想情况下,我会滚动一个 sub 来接收两个文件名和 return 1
或 return 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 发行版一起提供。
【问题讨论】:
为什么不使用差异? -- 如果你在 *nix @heferav :将它可以熟练处理的内容呈现给 Perl。我在 Unix 编程方面并没有真正做太多,仅此而已;) 很好。阅读此手册页ss64.com/bash/diff.html,diff 实用程序是专门为突出两个文本文件之间的差异而创建的。diff --brief
然后检查它的退出值就足够了。
【参考方案1】:
在core。
use File::Compare;
if (compare("file1", "file2") == 0)
print "They're equal\n";
【讨论】:
哇!我知道这很简单。File::Compare
大致相当于只打开文件并逐行读取它们(或者,如果您使用第三个参数,则逐块读取)。如果您担心性能,您可能需要在调用之前检查文件大小和 inode 号。
实际上 File::Compare 已经检查了文件大小。查看来源cpan.uwinnipeg.ca/htdocs/perl/File/Compare.pm.html【参考方案2】:
您可以先进行几项 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";
【讨论】:
问题是在可移植脚本语言 (Perl) 的上下文中。这个答案是特定于操作系统和文件系统的。 inode 是唯一且可比较的假设在 Windows(所有文件系统)甚至在 UNIX 上面向块的文件系统上都会失败,对于不同卷、分区、子卷等上的 inode 也会失败。以上是关于如何使用 Perl 判断两个文件的内容是不是相同?的主要内容,如果未能解决你的问题,请参考以下文章