web-dev-qa-db-ja.com

Linuxマージフォルダ:rsync?

フォルダのコピーが2つあります

src/
dest/

次のようにして、それらをマージしたいと思います。

ファイルがsrcにのみある場合、それをdestに移動したい

ファイルがdestのみにある場合は、無視してIEそのままにしておきます。

ファイルが両方にある場合および同じ内容(つまり同じサイズと日付)の場合は、srcから削除します

ファイルが両方にあり、notの内容が同じである場合は、srcに残して、手動でマージできるようにします。

この最後のカテゴリに含めることができるのはごく少数のファイル(合計ファイルの0%から5%の間)だけですが、両方のファイルと同じファイルを両方から分離する方法はわかりませんが、異なります。

rsyncを使用してこれを行う方法を見つけようとしましたが、今のところ役に立ちません。

13
David Oneill

限られた機能のテストしか実行していないので、次のコマンド(--dry-run)に注意してください。

rsync -avPr --ignore-existing --remove-source-files src/ dest

末尾の/は、src自体をコピーするのではなく、srcに再帰するため、既存のパスを維持する必要があることに注意してください。

--ignore-existingフラグを--remove-source-filesフラグと組み合わせて使用​​することにより、srcからdestに同期されたファイル、つまり以前はdestのみに存在しなかったファイルのみをsrcから削除します。

同期されていないファイル、つまりsrc /のようにdest /にすでに存在するファイルを削除するには、次を使用できます。

for file in `find src/ -type f`; do diff $file `echo $file | sed 's/src/dest/'` && rm $file || echo $file; done

または

find src -type f -exec bash -c 'cmp -s "$0" "${0/#src/dest}" && rm "$0"' {} \;

ファイル名に空白/新しい行/…を含めることができる場合、特殊文字に関するGillesのコメントに関しては、これは確かに注意すべき点であり、多くの解決策があります。最も簡単な方法は、すべての削除の前にプロンプ​​トを表示するrmに-iを渡すことです。ただし、src /またはその親パスが検索用に提供されている場合、完全修飾パスを使用すると、すべてのファイル名が引用符なしでdiffコマンドとrmコマンドの両方で適切に処理されます。

17
Tok

ユニゾンはあなたが探しているツールです。 GUIを好む場合は、unison-gtkを試してください。しかし、私はそれが同様のファイルを削除するとは思わない:ユニゾンは両方のディレクトリを同一にしようとします。それでも、1)コピーするファイルを簡単に特定できます。 2)手動マージが必要なもの。

6
simonp

次のスクリプトは、合理的に動作するはずです。ファイルをソースから宛先に移動し、必要に応じてファイルを上書きしたりディレクトリを作成したりすることはありません。宛先に対応する異なるファイルがあるソースファイルは、通常のファイルまたはディレクトリではないファイル(シンボリックリンクなど)と同様に、そのまま残されます。ソースに残っているファイルは、競合しているファイルです。注意してください、私はそれをまったくテストしていません。

cd src
find . -exec sh -c '
    set -- "/path/to/dest/$0"
    if [ -d "$0" ]; then #  the source is a directory 
      if ! [ -e "$1" ]; then
        mv -- "$0" "$1"  # move whole directory in one go
      fi
    Elif ! [ -e "$0" ]; then  # the source doesn't exist after all
      :  # might happen if a whole directory was moved
    Elif ! [ -e "$1" ]; then  # the destination doesn't exist
      mv -- "$0" "$1"
    Elif [ -f "$1" ] && cmp -s -- "$0" "$1"; then  # identical files
      rm -- "$0"
    fi
  ' {} \;

別のアプローチは、たとえば funionfs または nionfs-Fuse を使用して、 nion mount ディレクトリを上下に実行することです。