4

そこで、実際に使用できるPerlの学習を支援するための小さなプロジェクトを思いつきました。アイデアは、2つのディレクトリ内のファイル変更日のリストを比較することです。1 FTPから、1つはローカルから、ローカルからのものが新しい場合はアップロードします(この部分は後で処理できます)。FTPからディレクトリを読み取り、ファイルを取得するための個別のスクリプトを作成しました(これらを組み合わせて、現時点でいじくり回す予定です)。もう1つは、2つのディレクトリ(ファイルリストは配列内にあります)にあるファイルのリストを比較します。ここで問題が発生します。2つのディレクトリを比較することができます。同じ名前のファイルを比較する方法を理解できないようです。1つのディレクトリにのみ存在するファイルがある場合、そのファイルを同じ配列位置にある別のファイルと比較します。

これは、ifステートメントを使用して非常に簡単に処理できます(簡単に言うことができますが、わかりません)が、どのパラメーターがそれを実行するかを理解することはできません。

私がこれまでに持っているもの:

 opendir(IMD, "/TRAINING/Perl") || die("Cannot open directory"); 
        @thefiles= readdir(IMD); 
        opendir(IMD2, "/TRAINING/Perl2") || die("Cannot open directory"); 
        @thefiles2= readdir(IMD2)

    foreach my $file (@thefiles) {
     #  if ($file != @thefiles2[$counter]){
        if (compare($file, @thefiles2[$counter]) == 0){
            print $file, " Matches ";
            print @thefiles2[$counter], "\n";   
            $counter++;
        }

     #  elsif ($file == @thefiles2[$counter]){  
        elsif (compare($file, @thefiles2[$counter]) != 0){
            print $file, " ";
            print "Does not match";
            print @thefiles2[$counter], "\n";
            $counter++; 
        }
    }

現時点では、同じ配列位置にあるファイルの名前を比較しているところですが、正しく機能するようになるまで、日付を使用するように変更します。すでに-Mを使用してそれを持っていましたが、現在と同じことをしていました。私はこれが私が必要としているものとはほど遠いことを理解しており、特に私のプログラミングは一般的にかなり初心者なので、本当にポインターが必要です。

本質的に私がやりたいこと、

If ($file1 !exists in $dir2){
    Print "not exists"
}
If ($file1 exists in $dir2){
    Compare its date with $file2 in $dir2 and print newer/older
}

今のところこれを機能させることができれば、私はそれを自分がやりたいようにゆっくりと変更することができます。

あなたたちが私に提供できるどんな援助にも感謝します。

4

2 に答える 2

2

まず、絶対パスではなく、相対パスを使用する必要があります。そうしないと、一致することはありません。したがって、「ベース」フォルダがたとえば/ Folderである場合、ファイル/ Folder / subfolder/fileはsubfolder/fileとして表される必要があります。

次のステップは、2つのハッシュをロードすることです。1つは最初の場所のファイルで、もう1つは2番目の場所のファイルでロードします。相対パスをキーとして使用すると、値は「同等性」を測定するために使用できる他の情報になります。変更時間、ファイルサイズ、またはMD5...必要なものは何でも。

次に、最初のハッシュのすべてのキーをステップスルーし、2番目のハッシュでそれぞれをチェックします。存在しない場合、ファイルは2番目の場所(新しいファイル?)にありません。存在する場合は、関連する「同等性」の値をチェックして、ファイルが更新/変更されたかどうかを確認できます。一致するものが見つかったら、2番目のハッシュからキーを削除します。次に、2番目のハッシュに残っているのは、最初の場所に存在しないファイル(削除されたファイル?)です。

ただし、これは注意が必要です。ミラーリングを試みる場合は、フォルダを認識している必要があります。ファイルを追加する場合は、最初にフォルダを並べ替えた順序で実行する必要があります...たとえば、subfolder /subfolder2/を作成する前にmkdirsubfolder/を実行します。

逆に、ものを削除しようとしている場合は、上記を逆にする必要があります...最初にファイルを削除してから、降順でフォルダを削除します...例:rmdirsubfolder/を試行する前にsubfolder/subfolder2/を削除します。

最後に、受信側のファイルの変更時間にも影響を与えることができる必要があります。ファイルをサーバーにFTPで転送すると、現在の時刻が取得されます。つまり、ファイルが新しいかどうかを判断する手段としてMTIMEを使用すると、ファイルが再び同等になることはありません。すべてのFTPサーバーにファイル時間を更新する手段があるわけではありません。

幸運を。結局、rsyncのようなものははるかに優れたソリューションです。

于 2012-12-03T02:18:59.940 に答える
1

まず、 readdirが順序付きリストを返すという仮定に頼ることはできません。したがって、他のディレクトリに存在しないファイルが存在する可能性があるため、ソートしても信頼できないため、インデックスだけを使用して比較するのは誤りです。また、コードがサブディレクトリで機能していません。使用できるオプション:

  • File::DirWalkなどのPerlモジュールを使用します。これにより、サブディレクトリを操作でき、statによって返されるファイルパスとその変更時間を含むハッシュを作成できます。
  • BSD mtree(8)などのUNIXユーティリティを使用する
于 2012-11-30T06:58:19.267 に答える