Как я могу использовать Perl, чтобы определить, идентично ли содержание двух файлов?

Этот вопрос прибывает из потребности гарантировать, что изменяется, я сделал для кодирования, не влияет на значения, которые он производит к текстовому файлу. Идеально, я прокрутил бы sub для взятия в двух именах файлов и return 1или return 0 в зависимости от того, идентично ли содержание или нет, пробелы и так далее.

Учитывая, что обработка текста является forté 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 распределений.

14
задан Zaid 17 May 2010 в 09:30
поделиться

2 ответа

Он находится в ядре ].

use File::Compare;

if (compare("file1", "file2") == 0) {
  print "They're equal\n";
}
31
ответ дан 1 December 2019 в 07:12
поделиться

Сначала вы можете выполнить пару проверок 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";
7
ответ дан 1 December 2019 в 07:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: