web-dev-qa-db-ja.com

2つのディレクトリを比較し、3つ目のディレクトリに相違をコピーする

Ubuntu 12.04を実行しているときに、folder1 /とfolder2 /の2つのディレクトリを比較して、folder3 /と異なるファイルをコピーします。ネストされたファイルもあるので、一致するサブディレクトリもコピーする必要があります

私に役立つ単一のコマンドはありますか?実行中の変更されたファイルの完全なリストを取得できます。

rsync -rcnC --out-format="%f" folder1/ folder2/

しかし、rsyncには、これらのファイルを別のターゲットディレクトリに「エクスポート」する機能がないようです。リストをcpまたは他のプログラムにパイプして、ディレクトリも作成されているときにファイルがコピーされるようにできますか?たとえば、私は試しました

rsync -rcnC --out-format="%f" folder1/ folder2/ | xargs cp -t folder3/

しかし、それはディレクトリも保持しません、それは単にfolder3 /内のすべてのファイルをコピーします

32
periklis

--compare-destを使用します。

Manページから:

--compare-dest = DIR-このオプションは、rsyncに宛先マシンのDIRを追加の階層として使用して、宛先ファイルを転送の実行と比較します(宛先ディレクトリにファイルがない場合)。送信者のファイルと同じファイルがDIRで見つかった場合、そのファイルは宛先ディレクトリに転送されません。これは、以前のバックアップから変更されたファイルのみのスパースバックアップを作成する場合に役立ちます。

最初に--dry-runで構文を確認します

rsync -aHxv --progress --dry-run --compare-dest=folder2/ folder1/ folder3/

次に、出力に満足したら:

rsync -aHxv --progress  --compare-dest=folder2/ folder1/ folder3/

この link は、-compare-destスコープを適切に説明しています。

38
smithian

この小さなスクリプトは機能するはずです。

folder1="firsts_folder/"
folder2="second_folder/"
folder3="target_folder"
for x in `rsync -rcnC --out-format="%n"  $folder1 $folder2`
    do
        if [ -d "$folder1/$x" ]; then
            mkdir -p "$folder3/$x"
        else
            cp -frv $folder1/$x $folder3/$x
        fi
done

ただし、diff -qrの出力を解析すると、各ファイルのパスと名前が一貫して提供されるため、より良い解決策になると私は思います。

[〜#〜]編集[〜#〜]

これは1つのコマンドで、コマンドは少し変更されています。しかし、それはfolder1folder3。また、フルパスでは機能しませんが、上記のスクリプトでもフルパスでは機能しません。

rsync -rcnC --out-format="\"%f\"" folder1/ folder2/ | xargs cp --parents -rfvt folder3/

\" in rsyncを使用して、空白を含むファイルやディレクトリで機能します。 Ubuntu 10.04でテスト済み。それが役に立てば幸い。

3
rsync -rcnC --out-format="%f" . ../folder2/ |xargs cp --parents -rt ../folder3/

これは、コマンドを発行する前に最初にfolder1に移動する場合は、私が思いつく最も簡単な形式です。

これは遅いオプションですが、要件を満たしていると思います。相対でないディレクトリ名を使用して実行できます。

rsync -rcnC --out-format="%n" folder1/ folder2/ |grep -vP "/$" |xargs -I{} rsync -R folder1/./{} folder3/

元のrsyncコマンドはそのままにしました。これは、正しいファイルリストを提供しているとのことでした(そして、私のテストファイルは明らかにあなたのファイルとは異なるため、確実に私がそれを台無しにした場合、正しいファイルリスト)。

grepは、rsyncの出力からディレクトリ名を削除するためのものです。

grepの出力は、rsyncを使用して別のxargsにパイプされます。パラメータfolder1/./{}では、追加の./を使用して、./{}で始まる相対ディレクトリを作成するようにrsyncに指示します。folder1/は無視されます。つまり、folder3/folder1/の作成を回避します。

私はこれをCentOS 6.4でのみテストできましたが、AFAIKはUbuntu 12.04でも同じように機能するはずです。

編集:smithianの答えは間違いなく優れていることに注意してください。しかし、元のrsyncコマンドは、目的の出力を提供していたため、そのまま使用できます。

2
s.co.tt