Как сопоставить одинаковые имена файлов и переименовать их так, чтобы инструменты сравнения, такие как Beyond Compare, рассматривали их как пару для выполнения двоичного сравнения?
Я ищу лучший подход к сравнению файлов, которые я считаю идентичными, но которые имеют разные имена файлов. Инструменты сравнения, такие как BeyondCompare, хороши, но они еще не обрабатывают разные имена файлов - при сравнении файлов в отдельных папках они пытаются сравнить файлы с одинаковыми именами с обеих сторон.
(Я не работаю на BeyondCompare или не заинтересован в нем, но я часто пользуюсь этим инструментом и нахожу его отличным функционалом).
Существует MindGems Fast Duplicate File Finder для сопоставления файлов в любом месте по нескольким деревьям папок, которые имеют разные имена, но это основано на проверках CRC. Я полагаю, я использую этот инструмент, но я только постепенно доверяю ему, пока нет ошибок, но не не доверяйте ему так же, как BeyondCompare. BeyondCompare предлагает полное решение для полного двоичного сравнения файла.
В моем случае файлы, как правило, имеют одинаковые имена, разница состоит в упорядочении слов, пунктуации, разнице в регистре и не во всех словах. Поэтому использовать фильтр регулярных выражений нелегко для сопоставления файлов, которые уже предоставляются некоторыми инструментами сравнения, такими как Beyond Compare, поскольку подстроки файлов могут быть не в порядке.
Я ищу способ сопоставления похожих имен файлов перед тем, как переименовать файлы, чтобы они были одинаковыми, а затем "подать" их на такой инструмент, как BeyondCompare. Решения могут быть сценариями или, возможно, в форме приложения.
На данный момент у меня есть идея для алгоритма (для реализации в Perl), чтобы соответствовать именам файлов, чтобы удовлетворить мою проблему, в результате чего имена файлов похожи, как описано выше.
Можете ли вы предложить что-то лучшее или совершенно другой подход?
Найти список файлов с одинаковым размером файла
Создайте хеш буквенно-цифровых подстрок из первого файла, используя не буквенно-цифровые символы или пробел в качестве разделителя
Создайте хеш буквенно-цифровых подстрок из второго файла, используя не буквенно-цифровые символы или пробел в качестве разделителя
Совпадение вхождений
Найти, какой файл имеет наибольшее количество подстрок.
Рассчитайте процентный показатель для сравнения в паре на основе количества совпадений, разделенного на наибольшее количество подстрок.
Повторите сравнение для каждого файла с каждым другим файлом с точным размером файла
Сортировка парных сравнений по процентным показателям, чтобы получить предложения файлов для сравнения.
Переименуйте один файл в паре, чтобы он совпадал с другим. Поместите в отдельные папки.
Запустите инструмент сравнения, как BeyondCompare с файлами, режим сравнения папок.
2 ответа
Поскольку у меня уже есть Fast Duplicate File Finder Pro, он выводит текстовый отчет о дубликатах в формате CSV и XML.
Я обработаю CSV, чтобы увидеть группировки и переименовать файлы, чтобы я мог выйти за пределы сравнения, чтобы выполнить полное двоичное сравнение с ними.
Обновить:
А вот и мой код. Этот сценарий Perl будет смотреть на каждую пару файлов (в сравниваемых каталогах / папках), которые являются одинаковыми, и переименовывать один из них, чтобы быть таким же, как другой, так что две папки могут быть запущены через Beyond Compare, который будет делать полное двоичное сравнение (если включена опция "Сгладить папки"). Двоичное сравнение подтверждает совпадение, что означает, что один из каждой дублирующейся пары может быть очищен.
#!/usr/bin/perl -w
use strict;
use warnings;
use File::Basename;
my $fdffCsv = undef;
# fixed
# put matching string - i.e. some or all of path of file to keep here e.g. C:\\files\\keep\\ or just keep
my $subpathOfFileToKeep = "keep";
# e.g. jpg mp3 pdf etc.
my $fileExtToCompare = "jpg";
# changes
my $currentGroup = undef;
my $group = undef;
my $filenameToKeep = "";
my $path = undef;
my $name = undef;
my $extension = undef;
my $filename = undef;
open ( $fdffCsv, '<', "fast_duplicate_filefinder_export_as_csv.csv" );
my @filesToRenameArray = ();
while ( <$fdffCsv> )
{
my $line = $_;
my @lineColumns = split( /,/, $line );
# is the first column and index value
if ( $lineColumns[0] =~ m/\d+/ )
{
$group = $lineColumns[0];
( $line ) =~ /("[^"]+")/;
$filename = $1;
$filename =~ s/\"//g;
if ( defined $currentGroup )
{
if ( $group == $currentGroup )
{
( $name, $path, $extension ) = fileparse ( $filename, '\..*"' );
store_keep_and_rename();
}
else # group changed
{
match_the_filenames();
( $name, $path, $extension ) = fileparse ( $filename, '\..*"' );
store_keep_and_rename();
}
}
else # first time - beginning of file
{
$currentGroup = $group;
( $name, $path, $extension ) = fileparse ( $filename, '\..*"' );
store_keep_and_rename();
}
}
}
close( $fdffCsv );
match_the_filenames();
sub store_keep_and_rename
{
if ( $path =~ /($subpathOfFileToKeep)/ )
{
$filenameToKeep = $name.$extension;
}
else
{
push( @filesToRenameArray, $filename );
}
}
sub match_the_filenames
{
my $sizeOfFilesToRenameArraySize = scalar( @filesToRenameArray );
if ( $sizeOfFilesToRenameArraySize > 0 )
{
for (my $index = 0; $index < $sizeOfFilesToRenameArraySize; $index++ )
{
my $PreRename = $filesToRenameArray[$index];
my ( $preName, $prePath, $preExtension ) = fileparse ( $PreRename, '\..*' );
my $filenameToChange = $preName.$preExtension;
my $PostRename = $prePath.$filenameToKeep;
print STDOUT "Filename was: ".$PreRename."\n";
print STDOUT "Filename will be: ".$PostRename."\n\n";
rename $PreRename, $PostRename;
}
}
undef( @filesToRenameArray ); @filesToRenameArray = ();
$currentGroup = $group;
}
Beyond Compare может сделать это. Просто выберите файл слева и файл для сравнения справа. Выберите "Сравнить" или используйте функцию выравнивания (правая кнопка мыши).