İki dizin ağacı verildiğinde, hangi dosyaların içeriğe göre farklı olduğunu nasıl öğrenebilirim?


786

İki dizin ağacı arasındaki farkları bulmak istiyorsanız, genellikle sadece yürütmek:

diff -r dir1/ dir2/

Bu, karşılık gelen dosyalar arasındaki farkların tam olarak ne olduğunu verir. Sadece içeriği farklı olan ilgili dosyaların listesini almakla ilgileniyorum. Bunun basitçe bir komut satırı seçeneğini geçirme meselesi olacağını varsaydım diff, ancak man sayfasında hiçbir şey bulamadım.

Herhangi bir öneri?



1
Dizinlerden biri ile ilgili olarak, sadece diğerinde ekstra olan dosyaları / dizinleri nasıl alabilirim?
Sandeepan Nath

dircmpunix üzerinde komut kullan (linux değil)
roblogic

Yanıtlar:


1118

Linux dediniz, bu yüzden şanslısınız (en azından ne zaman eklenmiş olduğundan emin olmalısınız):

diff --brief --recursive dir1/ dir2/ # GNU long options
diff -qr dir1/ dir2/ # common short options

İhtiyacınız olanı yapmalısınız.

Her iki dizinde de bulunmayan dosyalar için farklılıklar görmek istiyorsanız:

diff --brief --recursive --new-file dir1/ dir2/ # GNU long options
diff -qrN dir1/ dir2/ # common short options

12
Güzel. Ama daha kısa diff -qr dir1/ dir2/ve benim genişletilmiş versiyonudiff -qr dir1/ dir2/ | grep ' differ'
sobi3ch

1
@skv neden? Cevapla aynı komut. Sadece --briefkısayoluyla değiştirdim -q.
sobi3ch

2
@skv Orijinal sorunun tam olarak ne istediğini değil, aynı zamanda bu soruyu da cevaplamak için cevabı güncelleyin.
Mark Loeser

3
@MikeMaxwell Olması gerekiyor --brief. -briefolarak yorumlanır -b -r -i -e -fbayrak kümesi olarak değil tek seçenek olarak bir başka deyişle,.
daboross

2
@daboross: vay, uzun süredir Unix / Linux kullanıyorum ve '-' ve '-' arasında bir ayrım olduğunu hiç fark etmedim. (Başladığımda '-' var olduğunu düşünmüyorum.) Açıklama için teşekkürler!
Mike Maxwell

287

Kullandığım komut:

diff -qr dir1/ dir2/

Mark'ınkiyle tam olarak aynı :) Ama cevabı farklı bayrak türleri kullandığından beni rahatsız etti ve iki kez görünmemi sağladı. Mark'ın daha ayrıntılı bayraklarını kullanmak şöyle olur:

diff  --brief --recursive dir1/ dir2/

Diğer cevap mükemmel kabul edilebilir olduğunda yayınladığım için özür dilerim. Kendimi durduramadım ... daha az bilgiçlik için çalışıyorum.


3
tutarlılığı tamamen takdir edin - ama kendinizi kötü hissetmeyin; Mark'ın cevabını da iptal ettim;)
Gerard

10
.. bu yüzden SADECE farklı bir lezzet farklı bir tat koymak mantıklı mı? IMHO hayır! Her iki yanıtı da tek bir tutarlı cevaba birleştirmek mantıklı mı? Evet! ;)
sobi3ch

1
Sadece bir soru; ne anlama geliyor q? Bir şeyin kısaltması mı? Arkasında hiç mantık bulamıyorum q..
kramer65

3
@ kramer65 - "--brief" ile aynı, ama sanırım neden q? Belki de hızlı? "-b", man sayfasına göre "beyaz boşluk miktarındaki değişiklikleri yoksay" ile alınır.
FPC

4
@ kramer65 inanıyorum qiçindir quietgenellikle az ayrıntılı anlamı.
Gogeta70

105

Kullanmayı seviyorum git diff --no-index dir1/ dir2/, çünkü renk farklılıklarını gösterebilir (git config'te bu seçeneği ayarladıysanız) ve "az" kullanarak uzun sayfalanmış bir çıktıdaki tüm farklılıkları gösterdiği için.


25
Temiz. Git'in sadece dosyalarına karşı repoyu değil, keyfi dizinleri de farklılaştırabileceğini kim tahmin ederdi?
Dan Dascalescu

2
Perl script colordiff burada çok yararlıdır, svn ve normal diff ile kullanılabilir.
Felipe Alvarez

4
2 dirs'i ayrı git projeleri / depoları olarak karşılaştırırsanız --no-index, stackoverflow.com/a/1792477/473390 üzerine daha fazla şey eklemeniz gerekir . @ Alan-porter cevabını güncelledim.
sobi3ch

Bunu beğendim, ayrıca --name-status komut satırına eklerseniz , sadece değiştirilmiş / Eklendi / Silindi durumu için "M / A / D" bayrakları ile dosya adı listesini göstereceğini görüyorum .
gzh

Her iki dizin aslında .git klasörünü içerdiğinden, karşılaştırmadan nasıl hariç tutabilirim?
Muhamed Cicak

35

Bu iki komut temel olarak istenen şeyi yapar:

diff --brief --recursive --no-dereference --new-file --no-ignore-file-name-case /dir1 /dir2 > dirdiff_1.txt

rsync --recursive --delete --links --checksum --verbose --dry-run /dir1/ /dir2/ > dirdiff_2.txt

Aralarındaki seçim dir1 ve dir2'nin konumuna bağlıdır:

Dizinler iki ayrı sürücüde bulunduğunda, diff rsync'den daha iyi performans gösterir. Ancak karşılaştırılan iki dizin aynı sürücüde olduğunda, rsync daha hızlıdır. Çünkü diff, her iki dizine paralel olarak neredeyse eşit bir yük koyar ve iki sürücüdeki yükü en üst düzeye çıkarır.

rsync gerçekte karşılaştırmadan önce büyük parçalardaki sağlama toplamlarını hesaplar. Bu, i / o işlemlerini büyük parçalar halinde gruplandırır ve işler tek bir sürücüde gerçekleştiğinde daha verimli bir işleme yol açar.


3
rsync sadece hızlıdır da tek sürücülerde dosya, ancak örneğin subdirs dosyaları karşılaştırmak için allowes için rsync --options /usr /bin /var /sbin /lib /old_rootetkili bir akım kök karşılaştırır /(içindeki tüm subdirs belirterek) ve /old_root(bazı eski yedeği örneğin içeren /bir şeydir), diff -rteneke yapma. Aynı boyut, izin ve zaman damgalarına sahip dosyaların muhtemelen değişmediğini varsayarsanız, dışarıda bırakmak --checksumsize hangi dosyaların değişebileceğini son derece hızlı (eğer böyle değilse) kontrol sağlayacaktır.
Matija Nalis

1
Amacı nedir --deleteile rsync?
Tom Hale

2
--Delete'nin amacı, hedef dizinde (artık) kaynak
dizininde

2
Bu durumda ( --dry-runbayrakla) hiçbir şey gerçekten silinmez, rsyncyalnızca hangi dosyaların dir1'de olduğunu, ancak dir2'de olmadığını yazdırır
mata

11
Her --dry-runzaman yanlışlıkla unutmamak için koymanızı tavsiye ederim .
Dave Rager

22

Meld ayrıca iki dizini karşılaştırmak için harika bir araçtır:

meld dir1/ dir2/

Meld, dosyaları veya dizinleri karşılaştırmak için birçok seçeneğe sahiptir. İki dosya farklıysa, dosya karşılaştırma moduna girmek ve tam farkları görmek kolaydır.


2
Güzel. Ağaçlar üzerinde karşılaştırma yapmak için basit bir perl betiği yazdım ama sınırlamalara çarpıyorum. Bu bilet gibi görünüyor.
David Tonhofer

Tek sorun, grafiksel bir uygulama olduğu için komut dosyalarına borç vermemesidir. Ama GUI sakıncası yoksa güzel! Teşekkürler.
DeanM

meldAma büyük dizinlerde kullanılırsa korkunç halsiz buluyorum . Büyük dizinleri daha iyi işleyen bir şey var mı?
Popup

@ Popup, bildiğimden değil. Buna benzer bir şeyle farklı dosya adları bulabilirsiniz:find dir1 dir2 | cut -d/ -f2- | sort | uniq --unique
Alexander

1
@Alexander - Bu durumda meld <(find dir1 -ls ) <(find dir2 -ls), bash işlemi ikamesi kullanarak oldukça iyi çalıştığını görüyorum . (zsh's =(command)daha da iyi çalışır.)
Popup

10

Kanal vatandaşı 'billings' (freenode / # centos fame) yöntemini benimle paylaştı:

diff -Naur dir1/ dir2

Son dizinin eğik çizgi eklenmesi önemli değildir.

Ayrıca, -ufarkın bazı eski / sunucu sürümlerinde mevcut olmadığı anlaşılıyor .

Diffs'deki fark:

# diff -Nar /tmp/dir1 /tmp/dir2/
diff -Nar /tmp/dir1/file /tmp/dir2/file
28a29
> TEST

# diff -qr /tmp/dir1/ /tmp/dir2/
Files /tmp/dir1/file and /tmp/dir2/file differ

2
Bu --new-file/-Nda diff'in eksik dosyaların boş --text/-aolduğunu düşünmesine neden olur ve bu da tüm ikili girdilerin metin olarak değerlendirilmesine neden olur. Bu özel kullanım durumunun ters taraflarını görmüyorum.
phk

4

Diffoscope harika bir komut satırı tabanlı dizin dif aracıdır.

Özellikle o diff ki bu konuda böyle içine dosyaları:

Birçok türde arşivi özyinelemeli olarak açacak ve çeşitli ikili formatları karşılaştırmak için daha insan tarafından okunabilir forma dönüştürecektir. İki tarball, ISO görüntüsü veya PDF'yi kolayca karşılaştırabilir.

Sadece hangi dosyaların farklı olduğunu değil, aynı zamanda nasıl farklı olduklarını da söyleyecektir.


4

Diff'i bulmak için şu komutu kullanın:

diff -qr dir1/ dir2/

-r çok tüm alt dizinleri diff edecek -q dosyalar farklı zaman sadece rapor diff söyler.

diff  --brief dir1/ dir2/

--brief dizinde mevcut olan dosyaları gösterir.

Veya başka

farkı bulmak kolay grafik penceresinde gösterecek Meld kullanabilirsiniz.

meld  dir1/ dir2/

2
--briefve -qaynı seçenek. İfadeniz farklı gibi görünse de farklı değil.
Elijah Lynn

2

AyrıcaRsync ve öğelerini de kullanabilirsiniz find. Şunun için find:

find $FOLDER -type f | cut -d/ -f2- | sort > /tmp/file_list_$FOLDER

Ancak aynı adlara ve aynı alt klasörlere, ancak farklı içeriğe sahip dosyalar listede gösterilmez.

GUI hayranı iseniz, kontrol edebilirsiniz Meld @Alexander bahsetti. Hem pencerelerde hem de linux'da iyi çalışır.


1

DirA ve dirB arasındaki farkları bildirirken güncelleme / senkronizasyon.

rsync -auv <dirA> <dirB>

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.