コマンドラインでのファイルのコピーについてヘルプが必要です

コマンドラインでのファイルのコピーについてヘルプが必要です

なんと 700 GB もあるフォルダがあり、そのファイルの一部が重複しています。同じ名前のファイルも多く、重複しているファイルもあれば、そうでないファイルもあります。基本的に、そのフォルダには約 30 個のフォルダがあり、ファイルとフォルダが詰まっています。この 700 GB のフォルダ内のすべてのファイルを再帰的に取得し、非再帰的に別のディレクトリにコピーしたいと考えています。競合はサイズに基づいて処理されます。2 つのファイルの名前が同じでサイズが同じ場合、ファイルはスキップされますが、2 つのファイルの名前が同じでサイズが異なる場合は、両方のファイルが保持されます。これを行う方法はありますか?

答え1

複雑な質問です。重複した名前を変更する必要があるだけでなく、名前を変更重複したオブジェクトは、(おそらく) 以前に名前が変更されたすべての「仲間」に対してサイズ別にチェックする必要があります。

何をするのか

私が確認した限り (およびテストした限り)、以下のスクリプトがそれを実行します。重複の可能性があるファイルの名前を などに変更し[dupe_1]<file>([dupe_1]<file>サイズが異なる場合)、名前を変更するたびに、ファイルのサイズが移動された重複ファイルまたはターゲット ディレクトリ内の名前が変更されたバージョンと一致するかどうかを確認します。

#!/usr/bin/env python3
import shutil
import os

#--- set the directory, the same as the first script
dr = "/path/to/recursive/source_directory"
dr2 = "/path/to/flat/target_directory"
#---

def check_dupe(src, trg):
    return os.stat(src).st_size == os.stat(trg).st_size

for root, dirs, files in os.walk(dr):
    for file in files:
        # define src, target
        src = root+"/"+file; trg = dr2+"/"+file
        if not os.path.exists(trg):
            # if target does not exist: move file
            shutil.copy(src, trg)
        else:
            n = 1
            # rename the file, check after every renaming if file exists, if size differs
            while os.path.exists(trg):
                test = check_dupe(src, trg)
                if test != True:
                    trg = dr2+"/[dupe_"+str(n)+"]"+file
                    n += 1
                else:
                    break
            if test != True:
                shutil.copy(src, trg)

使い方

  1. スクリプトを空のファイルにコピーし、reorganize.py
  2. スクリプトの先頭セクションで、ソースディレクトリとターゲットディレクトリへのパスを設定します。
  3. 次のコマンドで実行します:

    python3 /path/to/reorganize.py
    

ノート

  • まずは少量のサンプルでテストしてください
  • これは、巨大な「フラット」ディレクトリ。nautilus では参照できません。

答え2

これを試して:

cd [folder_name]
for file in ./*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*
do
    if [ -e [destination_folder]/"$file" ]; then
        if [ `du -s "$file" | cut -d ' ' -f 1` -eq `du -s [destination_folder]/"$file" | cut -d ' ' -f 1` ]; then
            false
        else
            cp "$file" [destination_folder]/"$file"...
        fi
    else
        cp "$file" [destination_folder]/
    fi
    echo "$file copied"
done

関連情報