3

同一であると思われるがファイル名が異なるファイルを比較するための最良のアプローチを探しています。BeyondCompareのような比較ツールは優れていますが、まだ異なるファイル名を処理していません。別々のフォルダーにあるファイルを比較する場合、どちらかの側に同じ名前のファイルとの比較を試みます。

(私はBeyondCompareで働いていないか、金銭的な利害関係はありませんが、このツールを頻繁に使用していて、いくつかの優れた機能があることがわかりました)。

異なる名前を持ついくつかのフォルダツリー全体の任意の場所にあるファイルを照合するためのMindGemsFastDuplicate File Finderがありますが、これはCRCチェックに基づいています。私はこのツールを使用していますが、徐々に信頼しているだけです。これまでのところ、障害はありませんが、 BeyondCompareほど信頼してはいけません。BeyondCompareは、ファイルに対して完全なバイナリ比較を行うという完全な心構えを提供します。

私の場合、ファイルの名前は似ている傾向があります。違いは、単語の順序、句読点、大文字と小文字の違いであり、すべての単語が存在するわけではありません。したがって、ファイルのサブストリングが順序どおりになっていない可能性があるため、正規表現フィルターを使用してBeyondCompareなどの一部のdiffツールが既に提供しているファイルを照合するのは簡単ではありません。

ファイルの名前を同じに変更してから、BeyondCompareなどのツールに「フィード」する前に、類似したファイル名を一致させる方法を探しています。ソリューションは、スクリプトまたはおそらくアプリケーションの形式である可能性があります。

現時点では、問題に合わせてファイル名を一致させるアルゴリズム(Perlで実装する)のアイデアがあります。これにより、ファイル名は上記のようになります。

より良い、または完全に異なるアプローチを提案できますか?

  1. まったく同じファイルサイズのファイルのリストを検索する

  2. 英数字以外の文字またはスペースを区切り文字として使用して、最初のファイルから英数字の部分文字列のハッシュを作成します

  3. 英数字以外の文字またはスペースを区切り文字として使用して、2番目のファイルから英数字の部分文字列のハッシュを作成します

  4. 一致するオカレンス

  5. サブストリングの数が最も多いファイルを見つけます。

  6. 一致の数をサブストリングの最大数で割った値に基づいて、ペアの比較のパーセンテージスコアを計算します。

  7. 正確なファイルサイズを持つ他のすべてのファイルと各ファイルの比較を繰り返します

  8. ペアの比較をパーセンテージスコアで並べ替えて、比較するファイルの提案を取得します。

  9. ペアの一方のファイルの名前を変更して、もう一方のファイルと同じにします。別のフォルダに配置します。

  10. BeyondCompareのような比較ツールをファイル、フォルダー比較モードで実行します。

4

2 に答える 2

1

Fast Duplicate File Finder Pro を既に持っているので、これは重複のテキスト レポートを CSV および XML 形式で出力します。

CSV を処理してグループ化を確認し、ファイルの名前を変更して、比較を超えて完全なバイナリ比較を実行できるようにします。

アップデート:

そして、ここに私のコードがあります。この Perl スクリプトは、(比較対象のディレクトリ/フォルダー内の) 同じファイルの各ペアを調べ、そのうちの 1 つの名前をもう一方のファイルと同じ名前に変更して、2 つのフォルダーを Beyond Compare で実行できるようにします。完全なバイナリ比較 (フォルダーのフラット化オプションがオンになっている場合)。バイナリ比較によって一致が確認されるため、各重複ペアの 1 つを削除できます。

#!/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;
    }
于 2012-01-31T12:45:25.163 に答える