2 dizini karşılaştırın ve 3. dizindeki farklılıkları kopyalayın


32

Ubuntu 12.04'ü çalıştırarak, 2 dizini karşılaştırmak, klasör1 / ve klasör2 / demek, ve klasör3 / 'den farklı tüm dosyaları kopyalamak istiyorum. İç içe geçmiş dosyalar da vardır, bu nedenle eşleşen alt dizinler de kopyalanmalıdır

Bana yardımcı olacak tek bir komut var mı? Çalışan değişen dosyaların tam listesini alabilirim:

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

Ancak rsync, bu dosyaları farklı bir hedef dizinde "dışa aktarma" yeteneğine sahip görünmüyor. Dizinler de oluşturulurken dosyaların kopyalanması için listeyi cp ya da başka bir programa aktarabilir miyim? Mesela denedim

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

ancak bu, dizinleri de koruyamazdı, yalnızca folder3 / içindeki tüm dosyaları kopyalardı.


Muhtemelen bir kombinasyonunu diff -qrve awklistesini oluşturmak için kullanırdım, sonra rsync...
yine de

rsync'i listeyle nasıl kullanırım?
periklis

Ben bir for-loop çalıştırabilir ya da rsync --include-from=FILEseçeneği kullanırdım .
ewwhite

(tembel olmayın ...) Ama aşağıdaki rsync çözümü zarif.
ewwhite

Yanıtlar:


38

Kullanımı - compare-dest.

Man sayfasından:

--compare-dest = DIR - Bu seçenek, rsync'e, hedef dosyaları aktarma işlemleriyle karşılaştırmak için (dosyaları hedef dizinde yoksa) hedef makinedeki DIR'ı ek bir hiyerarşi olarak kullanma talimatını verir. DIR'de gönderenin dosyasıyla aynı olan bir dosya bulunursa, dosya hedef dizine DEĞİLDİR. Bu, önceki bir yedekten değiştirilen dosyaların yalnızca çok az bir yedeğini oluşturmak için yararlıdır.

İlk önce --dry-run ile sentaksını kontrol et

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

Öyleyse bir kez çıktıdan memnun kaldığınızda:

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

bu bağlantının - compare-dest kapsamının iyi bir açıklaması vardır.


1
Bunun için teşekkürler, bu parametrenin man sayfa açıklamasını anlamadım. İlgilenen herkes için yaptımrsync -rcC --compare-dest=folder2/ folder1/ folder3/
periklis

OsX kullanıcıları için hızlı not. Ben rsync version 3.1.1 protocol version 31anlamıyor benim yerel ve rsync ~/yollarını --compare-destparam.
Jevgeni Smirnov

4
Benim --compare-destiçin mutlak bir yol gerekli.
palswim

Yazarın veya OP'nin seçenekleri ile benim için işe yaramadı. Yani çıkışları fonts/Makefile.inher ikisinde de aynıdır dosya, folder2ve folder1dirs.
Hi-Angel

3

Bu küçük senaryo çalışmalı:

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

Ancak, diff -qr'nin ayrıştırma çıktısının daha iyi bir çözüm olacağını düşünüyorum çünkü her dosya için tutarlı bir yol ve ad veriyor.

DÜZENLE

Bu, bir komut olurdu, komutunuz biraz değiştirildi. Ancak folder1altında yaratacaktır folder3. Ve tam yollarla çalışmaz, ancak yukarıdaki komut dosyası tam yollarla çalışmaz.

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

Kullandığım \"içinde rsynco dosya ve dizinleri boşlukları içeren çalışması için. Ubuntu 10.04'te test edilmiştir. Umarım yardımcı olur.


Bunun için teşekkürler, tek bir komutun var olacağını
ummuştum

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

folder1Emri vermeden önce ilk önce inmeye istekliysen, bulabildiğim en basit form bu .

Bu yavaş seçenek, ancak gereksinimlerinizi karşıladığına ve göreli olmayan dizin adları kullanılarak çalıştırılabileceğine inanıyorum:

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

Özgün rsynckomutunuzu yalnız bıraktım , çünkü size doğru dosya listesini verdiğini söylediniz (ve test dosyalarım sizinkinden açıkça farklıydı, bu yüzden eğer karışık olursam doğru dosya listesini alacağımı kesin olarak söyleyemem). Bununla).

grepÇıkışından itibaren dizin adları kaldırmak için vardır rsync.

Daha grepsonra çıkışı rsynckullanılarak başka bir boruya aktarılır xargs. Paragrafta folder1/./{}, ekstra ./, rsync'e ./{}görmezden gelen göreceli dizinleri yaratmasını söylemek için kullanılır folder1/. Başka bir deyişle, oluşturmaktan kaçınır folder3/folder1/.

Bunu yalnızca CentOS 6.4'te test edebildim, ancak AFAIK, Ubuntu 12.04'te aynı şekilde çalışmalıdır.

EDIT: Smithian'ın cevabının kuşkusuz daha iyi olduğunu not etmeliyim , ancak asıl rsynckomutunuzla inceliğini yapmak için dokunuşuyla bıçaklama yapmak istedim .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.