Ответ 1
Это в core.
use File::Compare;
if (compare("file1", "file2") == 0) {
print "They're equal\n";
}
Этот вопрос связан с необходимостью обеспечения того, чтобы изменения, внесенные мной в код, не влияли на значения, которые он выводит в текстовый файл. В идеале, я бы свернул суб, чтобы взять два имени файла и return 1
или return 0
в зависимости от того, идентичны ли они или нет, пробелы и все.
Учитывая, что текстовая обработка Perl forté, довольно просто сравнить два файла и определить, идентичны они или нет (код ниже непроверен).
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.
Это в core.
use File::Compare;
if (compare("file1", "file2") == 0) {
print "They're equal\n";
}
Есть несколько проверок 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";