フォルダのコピーが2つあります
src/
dest/
次のようにして、それらをマージしたいと思います。
ファイルがsrc
にのみある場合、それをdest
に移動したい
ファイルがdest
のみにある場合は、無視してIEそのままにしておきます。
ファイルが両方にある場合および同じ内容(つまり同じサイズと日付)の場合は、src
から削除します
ファイルが両方にあり、notの内容が同じである場合は、src
に残して、手動でマージできるようにします。
この最後のカテゴリに含めることができるのはごく少数のファイル(合計ファイルの0%から5%の間)だけですが、両方のファイルと同じファイルを両方から分離する方法はわかりませんが、異なります。
rsync
を使用してこれを行う方法を見つけようとしましたが、今のところ役に立ちません。
限られた機能のテストしか実行していないので、次のコマンド(--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コマンドの両方で適切に処理されます。
ユニゾンはあなたが探しているツールです。 GUIを好む場合は、unison-gtkを試してください。しかし、私はそれが同様のファイルを削除するとは思わない:ユニゾンは両方のディレクトリを同一にしようとします。それでも、1)コピーするファイルを簡単に特定できます。 2)手動マージが必要なもの。
次のスクリプトは、合理的に動作するはずです。ファイルをソースから宛先に移動し、必要に応じてファイルを上書きしたりディレクトリを作成したりすることはありません。宛先に対応する異なるファイルがあるソースファイルは、通常のファイルまたはディレクトリではないファイル(シンボリックリンクなど)と同様に、そのまま残されます。ソースに残っているファイルは、競合しているファイルです。注意してください、私はそれをまったくテストしていません。
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 ディレクトリを上下に実行することです。