“ name(1)”、“ name(1)(1)”などの構造を持つ重複フォルダをマージする方法


1

私のGoogle Filestream、Google Drive、Synology CloudSyncの間で同期をとると、すべてが混乱してしまい、フォルダ名に "(1)"や "(2)"などが続く何百という複製フォルダが残されてしまいました。 "(1)(1)(1)"まで

これらのフォルダを結合できるプログラムまたはスクリプトを知っていますか。

最上位のフォルダ構造の例:

1100 Beetledwarf - Happy ATE
1100 Beetledwarf - Happy ATE (1)
1100 Beetledwarf - Happy ATE (2)
1100 Beetledwarf - Happy ATE (3)
1100 Beetledwarf - Happy ATE (3) (1)
1100 Beetledwarf - Happy ATE (3) (1) (1)
1100 Beetledwarf - Happy ATE (4)
1100 Beetledwarf - Happy ATE (5)
1100 Beetledwarf - Happy ATE (6)

サブフォルダにも同じ問題がある場合があるので、プログラムまたはスクリプトは、すべてのサブフォルダに対してその命名パターンに従うフォルダをマージできる必要があります。次に例を示します。

第2レベルのフォルダの例

1100 Beetledwarf - Happy ATE (6)
    Analysis
    Analysis (1)
    Smirckle_HL
    Smirckle_HL (2)
    Pending Reports
    Photos & Logos

ファイルをコピーするのに長い時間がかかるが移動がほとんど瞬間的であるので最もよい解決策はまた私がそれらをコピーするのではなくファイルを移動することを可能にするでしょう。

私がすでに試したことのリストですが、どれも "name(1)"フォルダ構造を扱うことができず(今のところわかります)、それらすべてがファイルを移動するのではなくコピーします。

  • WinMerge for Windows 10< - Googleドライブのファイルをコピーしようとすると失敗します( "DOSコマンドはサポートされていません"などが返されます)。
  • MacOS用に開発されました。 < - 遅い
  • OS Xで "ditto"コマンドを使ったターミナル< - これまでのところ最高のオプション。

ご協力いただきありがとうございます!


私があなたの言うことを正しく理解していれば、インターネット接続を通してあなたのケースでファイルを移動することはそれらをコピーすることと同じ時間がかかります。あなたはそれをファイルの移動と混同します 内に HDパーティション、それは速いです。パーティション間、HD間、PC間などでそれらを移動すると、通常はかなり時間がかかります(特定の構成では例外を考慮しないでください)。
Albin

おかげで、それは無関係なので私は私のインターネット接続についてのビットを削除しました。 WindowsとMac OSでGoogleファイルストリームを使用する場合、ファイルを移動すると、HDパーティション内でファイルを移動するのと同じです。その後、OSは通常、データをドライブ上の新しい場所にコピーします。この場合、HDはインターネット経由で接続されているため、コピーにはさらに時間がかかります。乾杯!
Josh

こんにちは。私はあなたの質問を具体的に解決するためにpyhtonスクリプトに取り組んでいます。それは適度に準備ができています、しかし残念なことに私は月曜日まで=(私が旅行するので)まで(重要な)最後の仕上げ(安全装置)をするのにより多くの時間を費やすことができません。その前に答えに出くわしたのであれば、まあ - とにかくあなたにとって素晴らしい= Dですが、見つからない場合は、これを終えてanswer =としてここに投稿できます。良い一日を過ごしてください。
Vinícius M

回答:


1

これは私がLinuxで試すアプローチです。私はGoogle Filestream、Google Drive、Synology CloudSyncのいずれにも慣れていないので、そのソリューションがまったく適用できるかどうかわかりません。それでも私はこれが少なくともあなたにいくつかのアイデアを与えることを願っています。


仮定

  • ディレクトリツリーに共有をマウントすることができます。 mvcp そして他の普通のツールはディレクトリをあたかもローカルであるかのように扱うことができます。
  • すべてのファイルを削除した後に同一になるパスを持つファイル (N) 文字列は、実際には同じファイル(ディレクトリ)のインスタンスです。
  • 同じファイルのインスタンスは1つのファイルだけを残します。
  • 同じディレクトリのインスタンスは、それらのコンテンツを単一のディレクトリにマージする必要があります。
  • あなたは私がここで使うすべてのツールを使うことができます。

手順

何かをする前に答え全体を読んでください。

いくつかのステップはスクリプトとして書くことができると思いますが、解決策は 非常に実験的 何が起こるかに注意を払いながら、手で、段階的にそれを行う方が良いです。

  1. シェルで cd マウントポイントに移動して呼び出す find . | vidir -;お好みのテキストエディタを使用してください。 kate、 このような:

    find . | EDITOR=kate vidir
    

    これにより、すべてのオブジェクトのリストが表示されたエディタが開きます。各オブジェクトの前にはそれぞれ固有の番号が付いています。内容を変更して(一時)ファイルを保存してエディタを閉じると、すべての変更が適用されます。一般的にこれはあなたができることです:

    • パスを変更してファイルまたはディレクトリを移動(名前変更)する。
    • ファイルまたはディレクトリを削除するには、行を削除します。
    • ファイルを交換するために2つ以上の数字を交換します(あなたはそれを必要としません)。

    新しいコンテンツに取得したいディレクトリツリーが記載されていることが確実でない限り、ファイルを保存しないでください。

  2. エディタからコンテンツをにコピーします。 別の ファイル。重要なのは、それを使って作業し、正しい結果が得られたと確信できる場合にのみ結果を貼り付ける(そして保存する)ことです。特に明記しない限り、次の手順で新しいファイルを参照します。

  3. つかいます sed またはすべてを取り除くための他のツール (N) 文字列(先頭のスペースに注意してください)。この時点で、あなたは「きれいな」パスを得るはずです、それらの多くは一度以上起こるでしょう(異なった数でによって与えられる) vidir

  4. つかいます sort -k 2 これらのパスに従ってソートします。ありがとう -s 前者 Analysis まだ前者に先行するべきです Analysis (1)

  5. つかいます uniq -f 1 重複したパスを削除します。今すぐ任意のパスが一度だけ発生します。

  6. 結果にエンコードされたディレクトリ構造の正当性を再確認してください。

  7. 結果を元のエディタに貼り付け、ファイルを保存してエディタを終了します。 vidir 足りない番号に関連付けられているオブジェクトを削除し、残っている番号に関連付けられているオブジェクトを移動します。


テスト

私が最初に使うだろう この解決策 ディレクトリ構造を複製するには

cp -a --attributes-only /mountpoint/ /guinea_pig_dir/

空のファイルを作成して手順をテストします。これは問題があればそれを明らかにし、うまくいけばメソッドを改善することができます。


考えられる問題

  1. vidir いくつかの非標準文字を扱うことを拒否します。

  2. 一般に、オブジェクトの順序は重要です。のようなオブジェクトを生成する落とし穴はほとんどありません foo~ または foo~1foo~2 と衝突したとき foo。衝突が発生しないようにディレクトリツリーを「縮小」しますが、それでもすべてのシナリオを調査したわけではありません。私は本当にあなたが試すべきだと思います /guinea_pig_dir/ そしてあなたが得るものを見なさい。トラブルの場合 多分 賢い sort の間に find そして vidir 役立ちます。


1

以下はこのタスクを実行するbashスクリプトです。それは上で動作しますrsyncを使ったMSYS2 Bashを追加しました。それはこの関連質問からここに取られます:

特定のサフィックスを持つファイルとフォルダーを重複排除するためのスクリプト

#!/usr/bin/bash
IFS=$'\n';
set -f
#Go deepest first to deal with copies within copied folders.
for copy in $(find . -regextype posix-egrep -regex "^.*\ \([0-9]+\)\s*(\.[^/.]*)?$" | awk '{print length($0)"\t"$0}' | sort -rnk1 | cut -f2-); do
    orig=$(rev <<< "$copy" | sed -E 's/\)[0-9]+\(\ //' | rev)
    if [ "$orig" != "$copy" ]; then
        if [ -f "$orig" ]; then
            if [ -f "$copy" ]; then
                echo "File pair: $orig $copy"
                if diff -q "$orig" "$copy" &>/dev/null; then
                    echo "Removing file: $copy"
                    rm -f "$copy";
                fi
            fi           
        fi
        if [ -d "$orig" ]; then
            if [ -d "$copy" ]; then
                echo "Folder pair: $orig $copy"
                if rmdir "$copy" &>/dev/null; then
                    #If the "copy" was an empty directory then we've removed it and so we're done.
                    echo "Removed empty folder: $copy"
                else
                    #Non-destructively ensure that both folders have the same files at least.                    
                    rsync -aHAv --ignore-existing "$orig/" "$copy" &>/dev/null
                    rsync -aHAv --ignore-existing "$copy/" "$orig" &>/dev/null
                    if diff -qr "$orig" "$copy" &>/dev/null; then
                        echo "Removing folder: $copy"
                        rm -rf "$copy";
                    fi            
                fi
            fi
        fi
    fi
done
unset IFS;
set +f

このスクリプトで開始ディレクトリを設定する方法私がそれをテストするときと最終的なロールアウトのときの両方で、私はそれが私のファイルの特定のサブセットで動作するようにしたいだけです。例: 'G:\ My Drive \ Deduplicate_Test_Folder' PS:素晴らしい反応をありがとう。
Josh

そのフォルダから始めてください。 (すなわち cd そこ。)
cfp
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.