Bagaimana Anda membandingkan dua folder dan menyalin perbedaannya ke folder ketiga?

23

Anda punya tiga folder:

  • folder saat ini , yang berisi file-file Anda saat ini
  • folder lama , yang berisi versi lama dari file yang sama
  • perbedaan folder , yang hanya folder kosong

Bagaimana Anda membandingkan yang lama dengan yang sekarang dan menyalin file yang berbeda (atau yang sama sekali baru) saat ini dengan perbedaan ?


Saya telah mencari di sekitar dan sepertinya hal yang mudah untuk ditangani, tetapi saya tidak bisa membuatnya bekerja dalam contoh khusus saya. Sebagian besar sumber menyarankan penggunaan rsync jadi saya berakhir dengan perintah berikut:

rsync -ac --compare-dest=../old/ new/ difference/

Namun, yang dilakukan adalah menyalin semua file dari yang baru ke yang berbeda , bahkan yang sama seperti yang lama .

Jika ini membantu (mungkin perintahnya baik-baik saja dan kesalahannya terletak di tempat lain), ini adalah bagaimana saya menguji ini:

  1. Saya membuat tiga folder.
  2. Saya membuat beberapa file teks dengan konten yang berbeda di yang lama .
  3. Saya menyalin file dari yang lama ke yang baru .
  4. Saya mengubah konten beberapa file di baru dan menambahkan beberapa file tambahan.
  5. Saya menjalankan perintah di atas dan memeriksa hasilnya dengan perbedaan .

Saya telah mencari solusi selama beberapa hari terakhir dan saya sangat menghargai bantuan. Itu tidak harus menggunakan rsync, tetapi saya ingin tahu apa yang saya lakukan salah jika memungkinkan.

Thane
sumber
kemungkinan duplikat dari Bagaimana cara menyimpan file yang diubah?
wingedsubmariner
@wingedsubmariner Saya tidak berpikir itu adalah duplikat, karena jawaban yang diterima pada pertanyaan terkait, adalah perintah yang ditanyakan oleh OP.
Bernhard
@ Bernhard Ah, salahku. Saya kira saya salah mengerti pertanyaan aslinya.
wingedsubmariner
@wingedsubmariner Jangan khawatir, Anda mengatakan "mungkin", dan saya setuju itu terlihat sangat mirip :)
Bernhard

Jawaban:

7

Saya tidak yakin apakah Anda dapat melakukannya dengan perintah linux yang ada seperti rsync atau diff. Tetapi dalam kasus saya, saya harus menulis skrip saya sendiri menggunakan Python, karena python memiliki modul "filecmp" untuk perbandingan file. Saya telah memposting keseluruhan skrip dan penggunaan di situs pribadi saya - http://linuxfreelancer.com/

Penggunaannya sederhana - berikan path absolut dari direktori baru, direktori lama dan direktori perbedaan dalam urutan itu.

#!/usr/bin/env python

import os, sys
import filecmp
import re
from distutils import dir_util
import shutil
holderlist=[]

def compareme(dir1, dir2):
    dircomp=filecmp.dircmp(dir1,dir2)
    only_in_one=dircomp.left_only
    diff_in_one=dircomp.diff_files
    dirpath=os.path.abspath(dir1)
    [holderlist.append(os.path.abspath( os.path.join(dir1,x) )) for x in only_in_one]
    [holderlist.append(os.path.abspath( os.path.join(dir1,x) )) for x in diff_in_one]
    if len(dircomp.common_dirs) > 0:
        for item in dircomp.common_dirs:
            compareme(os.path.abspath(os.path.join(dir1,item)), os.path.abspath(os.path.join(dir2,item)))
        return holderlist

def main():
 if len(sys.argv) > 3:
   dir1=sys.argv[1]
   dir2=sys.argv[2]
   dir3=sys.argv[3]
 else:
   print "Usage: ", sys.argv[0], "currentdir olddir difference"
   sys.exit(1)

 if not dir3.endswith('/'): dir3=dir3+'/'

 source_files=compareme(dir1,dir2)
 dir1=os.path.abspath(dir1)
 dir3=os.path.abspath(dir3)
 destination_files=[]
 new_dirs_create=[]
 for item in source_files:
   destination_files.append(re.sub(dir1, dir3, item) )
 for item in destination_files:
  new_dirs_create.append(os.path.split(item)[0])
 for mydir in set(new_dirs_create):
   if not os.path.exists(mydir): os.makedirs(mydir)
#copy pair
 copy_pair=zip(source_files,destination_files)
 for item in copy_pair:
   if os.path.isfile(item[0]):
    shutil.copyfile(item[0], item[1])

if __name__ == '__main__':
 main()
Daniel t.
sumber
21

Saya telah menemukan apa masalahnya dalam kasus saya:

File yang saya bandingkan memiliki stempel waktu yang berbeda. Saya seharusnya tidak menggunakan argumen -a , saya berasumsi karena rsync berusaha untuk melestarikan cap waktu ketika menyalin file. Perintah yang bekerja untuk saya adalah:

rsync -rvcm --compare-dest=../old/ new/ difference/
Thane
sumber
Saya pikir untuk menguji ini dengan opsi -a (arsip), Anda seharusnya terbiasa rsync -a"menyalin" file pada awalnya (atau setara dengan cp), kemudian dihapus atau dimodifikasi. (Saya suka tetap menggunakan rsync karena saya tahu itu konsisten sendiri tanpa memikirkan apa yang mungkin dilakukan.) Saya pikir itu seharusnya bekerja dengan perintah asli. Opsi -a termasuk -t (bandingkan dengan stempel waktu), yang merupakan alternatif untuk -c (bandingkan dengan checksum).
bijak
2
Menurut pendapat saya, jawaban ini harus yang diterima, karena jauh lebih sederhana. Juga, perintah hanya bekerja untuk saya ketika saya memberikan path lengkap untuk old/dan new/.
Yamaneko 3-15
Peringatan tampaknya adalah bahwa membandingkan-dest harus menjadi jalan relatif terhadap perbedaan seperti yang terlihat dari dalam dest aktual
Ryan Williams
1

Ini mungkin membantu beberapa pembaca: Di Windows, program freeware kecil yang lebih tua - Third Dir - melakukan apa yang diminta di sini. Tidak lagi tersedia melalui pengembang, Robert Vašíček. Tapi saya yakin itu dapat ditemukan melalui beberapa repositori online.

Berikut deskripsi pengembang, yang masih ada di situsnya:

Dir Ketiga: Penyinkronisasi direktori yang tidak biasa - berbagai file disalin ke direktori ketiga. Sangat berguna untuk mengekstraksi misalnya foto baru atau yang diedit dari pohon direktori besar pada disk tetap ke folder sementara, kemudian menambahkannya ke arsip CD (perhatikan - file asli dibandingkan dengan CD). Versi 1.4, ukuran 23kB. Dibuat 2005-02-12.

Sejarah: Versi 1.14 - Lebih efisien bila banyak dari sepuluh ribu file dibandingkan.

Steve
sumber
0

Cara rsync yang diberikan oleh Thane dengan tambahan Yamaneko bekerja sangat baik tetapi meninggalkan direktori kosong. Bagi saya solusi terakhir ada dalam dua langkah, pertama panggil rsync dengan path lengkap, lalu perintah find untuk menghapus semua direktori kosong:

rsync -rvcm --compare-dest=/tmp/org/ /tmp/new/ /tmp/difference/
find /tmp/difference/ -d -type d -empty -exec rmdir {} \; -print

Harap dicatat daripada bahkan dengan opsi --links, rsync tidak menyimpan tautan simbolik tetapi menyalin data tujuan.

PierreL
sumber
Perhatikan bahwa alih-alih -empty -exec rmdir {} \;Anda dapat menggunakan -empty -delete.
mivk
-3

Saya menggunakan dualpane XY Explorer (komersial), yang dapat melakukan banyak trik dan ini adalah salah satunya. Buka Currentdi satu panel dan Tua di yang lain. Aktifkan panel saat ini. Buka Panel > Sinkron Pilih. Ini memberi Anda 5 pilihan untuk memilih:

  1. Cocok (tercantum di keduanya)
  2. Unik (di panel aktif)
  3. Lebih baru (di panel aktif)
  4. File unik dan lebih baru (di panel aktif)
  5. Dipilih (yang dipilih di panel lain)

Sekarang Anda dapat menyalin pilihan yang dihasilkan dari Currentke tempat yang Anda inginkan. Saya menggunakannya untuk membandingkan mailfoldersdari instalasi lama dengan yang terbaru. Struktur foldernya cukup kompleks, tetapi (hampir) semuanya mbs-filesmemiliki nomor unik.

Jadi saya melakukan pencarian mbs-filesdi root lama mailfolder(dalam satu panel) serta pada yang terbaru (di panel lain) dan melakukan perbandingan pada hasil pencarian di setiap panel ( Sinkron Pilih Unik , untuk menemukan email yang hilang selama instal ulang)! Anda dapat mengatur banyak opsi juga.

Martijn Douwes
sumber
1
Jika Anda berbicara tentang perangkat lunak tidak standar, Anda harus menyertakan tautan. Jika maksud Anda XYplorer itu tidak akan membantu OP sama sekali.
Anthon