rsync dizinleri karşılaştırmak?


63

İki dizini rsync ile karşılaştırmak ve farklılıkları sadece yazdırmak mümkün mü? Kuru çalışma seçeneği var, ancak ayrıntı düzeyini belirli bir seviyeye çıkardığımda, karşılaştırılan her dosya gösteriliyor.

ls -alRve diffburada seçenek yok, çünkü kaynağında her çizgiyi farklı kılan bağlantılar var. (Tabii ki bu sütunu perl ile silebilirim.)


Yanıtlar:


46

Muhtemelen her rsync -avun --deleteiki yönde de benzer şeyler yapmak zorunda kalacaksın .

Ama gerçekte ne yapmaya çalışıyorsun?

Güncelleme :

rsync -avun --delete $TARGET $SOURCE |grep "^deleting " Hedef dizinde olmayan dosyaların bir listesini size verecektir.

Her satır baskılar nedeniyle "grep delet": delet ..file ing ..

rsync -avun $SOURCE $TARGET Size "farklı" dosyaların bir listesini verecektir (yeni dosyalar dahil).


49

Nils'in cevabına eklemek için (Google’dan bunun karşısına çıkan herkes için), varsayılan olarak rsyncyalnızca herhangi bir farklılık olup olmadığını anlamak için dosya boyutlarını ve değişiklik zamanlarını karşılaştırır. (Eğer bunlar farklıysa, daha fazlasını yapar, ancak eğer aynıysa, orada durur.)

Gerçek dosya içeriğini , aynı boyuta ve en son değişiklik zamanına sahip dosyalar için bile karşılaştırmak istiyorsanız , bir sağlama toplamı kullanarak dosyaları karşılaştırmayı -csöylemek rsynciçin bayrak ekleyin .

rsync -avnc $SOURCE $TARGET

(Bu -useçenek rsync'e, içeriğinden $TARGETdaha yeni olan ve $SOURCEiçeriği karşılaştırırken muhtemelen istemediğiniz dosyaları yoksaymasını söyler .)


6
Verilerin yalnızca aynı olmasını önemsiyorsanız --no-group --no-owner --no-perms --no-times, gereksinimlerinize dayanarak bunları eklemek veya bunların bir kombinasyonunu isteyebilirsiniz .
flungo

1
@flungo, ya da sadece ima seçeneklerin bir alt kümesini kullanmak -ayerine -a, örneğinrsync -rlDcnv --delete $SOURCE $TARGET
maxschlepzig

Lütfen --deletesadece mevcut dosyalarınızı listeye ekleyin$TARGET
Tom Hale

25

Sadece daha az aşina olanlar için rsync:

rsync -rvnc --delete ${SOURCE}/ ${DEST}
  • -n: En önemli bit - do not şey değişmez;
  • -rc: sadece içeriği karşılaştırın (aksi takdirde kullanın -ac);
  • -v : dosyaları listeler)
  • --delete : Tek yönlü bir fark değil, simetrik arayın.
  • Son olarak, /"dizine bak ve içeriğini hedefle karşılaştır" anlamına gelir .

Normal bir rsyncçıktı yazdıracak ,

  • her "yeni" dosya için bir satırda bir <dosyaadı> ile${SOURCE}
  • ve içindeki her "yeni" dosya için bir "silme <dosyaadı>" satırı ${DEST}.

  • Ayrıca, sembolik bağlantılar için "normal olmayan dosyayı <dosyaadı> atlamak" gibi bazı uyarılar da yazdırabilir .

PS. Bunun korkunç bir PS olduğunu biliyorum - ama gerçekten de aceleye eklendi. Yine de, bahse girerim bunu faydalı bulabilirim.


PPS. Alternatif olarak, biri de yapabilir

find $SOURCE -type f -exec md5sum {} \; | tee source.md5
find $DEST   -type f -exec md5sum {} \; | tee dest.md5

Dosya adları yeni satırlar içermiyorsa, her iki *.md5dosyayı ve diffonları sıralayabiliriz . (Bu yalnızca dosyalar için işe yarar, ancak bu, her iki taraftaki boş bir dizin algılanmaz.)


15

Şaşırtıcı bir şekilde, 6 yıl içinde hiçbir cevap -iseçeneği kullanmıyor ya da güzel çıktılar veriyor.

TLDR - Sadece bana komutları göster

rsync -rin --ignore-existing "$LEFT_DIR"/ "$RIGHT_DIR"/|sed -e 's/^[^ ]* /L             /'
rsync -rin --ignore-existing "$RIGHT_DIR"/ "$LEFT_DIR"/|sed -e 's/^[^ ]* /R             /'
rsync -rin --existing "$LEFT_DIR"/ "$RIGHT_DIR"/|sed -e 's/^/X /'

Çıktıyı anlamak

İşte çıktının bir örneği:

L             file-only-in-Left-dir
R             file-only-in-right-dir
X >f.st...... file-with-dif-size-and-time
X .f...p..... file-with-dif-perms

Her satırın ilk karakterine dikkat edin:

  • L/ Rdemek ki, / dir dosyası yalnızca Left veya Right dir'de görünür .
  • Xdosya her iki tarafta görünür ama (. bu durumda bir sonraki 11 karakter size daha fazla bilgi vermek aynı olmadığı anlamına gelir s, tve pfarklılıkları tasvir s ize, t ime ve p - deneyin daha fazla bilgi için sırasıyla ermissions man rsyncve aramak --itemize-changes) .

Kullanmak isteyebileceğiniz ilave seçenekler

Dosyaların sahibini / grubunu / izinlerini de karşılaştırmak istiyorsanız, sırasıyla -o/ -g/ seçeneklerini ekleyin -p. Son olarak, varsayılan olarak rsync'in aynı adı, zamanı ve boyutu varsa, iki dosyayı aynı şekilde değerlendirdiğini unutmayın. Bu son derece hızlıdır ve çoğu zaman fazlasıyla yeterlidir ancak% 100 olmasını istiyorsanız -c, aynı zamanda, aynı ad, zaman ve boyuttaki dosyaların içeriğini de karşılaştırmayı unutmayın.

TLDR - Sadece bana aramak için bir komut dosyası verin

İşte burada. Buna böyle çağır

diff-dirs Left_Dir Right_Dir [options]

"Kullanmak isteyebileceğiniz ilave seçenekler" bölümünde yukarıda belirtilen tüm seçenekler burada da geçerlidir.

#!/bin/bash
# Compare two directories using rsync and print the differences
# CAUTION: options MUST appear after the directories
#
# SYNTAX
#---------
# diff-dirs Left_Dir Right_Dir [options]
#
# EXAMPLE OF OUTPUT
#------------------
# L             file-only-in-Left-dir
# R             file-only-in-right-dir
# X >f.st...... file-with-dif-size-and-time
# X .f...p..... file-with-dif-perms
#
# L / R mean that the file/dir appears only at the `L`eft or `R`ight dir. 
#
# X     means that a file appears on both sides but is not the same (in which
#       case the next 11 characters give you more info. In most cases knowing
#       that s,t,T and p depict differences in Size, Time and Permissions 
#       is enough but `man rsync` has more info
#       (look at the --itemize-changes option)
#
# OPTIONS
#---------
# All options are passed to rsync. Here are the most useful for the purpose
# of directory comparisons:
#
# -c will force comparison of file contents (otherwise only
#    time & size is compared which is much faster)
#
# -p/-o/-g will force comparison of permissions/owner/group

if [[ -z $2 ]] ; then
    echo "USAGE: $0 dir1 dir2 [optional rsync arguments]"
    exit 1
fi

set -e

LEFT_DIR=$1; shift
RIGHT_DIR=$1; shift
OPTIONS="$*"

# Files that don't exist in Right_Dir
rsync $OPTIONS -rin --ignore-existing "$LEFT_DIR"/ "$RIGHT_DIR"/|sed -e 's/^[^ ]* /L             /'
# Files that don't exist in Left_Dir
rsync $OPTIONS -rin --ignore-existing "$RIGHT_DIR"/ "$LEFT_DIR"/|sed -e 's/^[^ ]* /R             /'
# Files that exist in both dirs but have differences
rsync $OPTIONS -rin --existing "$LEFT_DIR"/ "$RIGHT_DIR"/|sed -e 's/^/X /'

O nasıl çalışır?

Buna rsync diyoruz:

rsync -rin ...

İki dizin arasındaki farklar hakkında bilgi içeren her dosya için bir çıktı satırı yazdırmasını rsync'e -i( --itemize-changes) kullanırız . -nRsync'in normal davranışını bastırmamız gerekir (bu, dosyaları kopyalayarak / silerek iki diziyi senkronize etmeye çalışmaktır). ayrıca -rtüm dosyalar / alt dizinler için özyinelemeli çalışmamız gerekiyor .

Rsync'i üç kere ararız:

1. çağrı : Dir_B'de bulunmayan dosyaları yazdırır. Her --ignore-existingiki tarafta da bulunan dosyaları yoksaymak için kullanmamız gerekiyor .

rsync -rin --ignore-existing $DIR_A/ $DIR_B/

2. çağrı : Daha önce olduğu gibi fakat DIR_A / DIR_B sırasını değiştiriyoruz.

3. çağrı : Sonunda --existingsadece her iki dizde de görünen dosyaları kontrol etmek için kullanıyoruz .

rsync -rin --existing $DIR_A/ $DIR_B/

Diğerleri hakkında bir şey bilmiyorum, ama betiğinizi kullanıyorum. Harika iş! teşekkürler
Marinaio

7

Sorunuzdan , ls üzerinde diff kullanmak istemediğinizi , ancak diff'i dizinlerde özyinelemeli olarak da kullanabildiğinizi anlıyorum :

diff -rq DIR1 DIR2

2

Bunu işe almak için birkaç denememi aldı. Nils'in cevabı, ジ ョ ー ジ tarafından açıklandığı gibi $TARGETbir izlemenin sona ermesini gerektirir /.

İşte izini açıkça ekleyen bir sürüm /:

rsync -avun --delete ${TARGET}/ ${SOURCE}  | sed -ne 's/^deleting *//p'

Bu, ${SOURCE}dizinin altında bulunan ancak dizinin altında olmayan dosyaların listesini verir ${TARGET}.

Kullandığım sedlider kaldırmak için buraya deletingçıkış hatlarından ve sadece bu satırları yazdırmak için.

Bu rsyncseçeneği kullanmıyorum, -cçünkü dosya içeriğini karşılaştırmak benim kullanım durumlarım için çok daha yavaş olacak ve yalnızca dosya boyutlarını ve değişiklik zamanlarını karşılaştırmak da bu durumlarda yeterli görünüyor. Bilgisayarlarımın saat eğriltme problemlerinden muzdarip olduğundan veya zaman damgasını kötü yönde değiştiren bir şey olduğundan şüphelenmek için hiçbir nedenim yok. Ayrıca, -cbir dosyayı silme kararını değiştiremez, yalnızca dosyayı güncelleme veya saklama kararını değiştiremezsiniz.

Ben de kullanmak -uve -a(ziyade -rdaha sonra komut satırını yeniden kullanmak ve seçilen dizinleri ve dosyaları kopyalamak için bunu değiştirebilirsiniz, böylece) ${SOURCE}için ${TARGET}bu gibi:

rsync -avu ${SOURCE}/{dirA,dirB,fileX} ${TARGET}   # copy some files

0

Bunu yapmak için başka bir fikrim var:

rsync -rn --out-format=FILEDETAIL::%n  $TARGET $SOURCE  | grep "^FILEDETAIL"

Komutun çıktısı ile "FILEDETAIL ::" eşleştirebilirsiniz. Ayrıca, "FILEDETAIL ::" dizesini değiştirebilirsiniz. "% N", dosya adıdır.

-r Bu, rsync'e dizinleri tekrarlamalı olarak kopyalamasını söyler.

-n Bu, rsync'in hiçbir değişiklik yapmayan bir deneme çalıştırması yapmasını sağlar.

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.