Come si confrontano due cartelle e si copia la differenza in una terza cartella?


23

Hai tre cartelle:

  • cartella corrente , che contiene i file correnti
  • cartella vecchia , che contiene una versione precedente degli stessi file
  • differenza di cartella , che è solo una cartella vuota

Come si confronta il vecchio con il corrente e si copiano i file che sono diversi (o completamente nuovi) in corrente per differenza ?


Ho cercato dappertutto e sembra una cosa semplice da affrontare, ma non riesco a farlo funzionare nel mio esempio particolare. La maggior parte delle fonti ha suggerito l'uso di rsync, quindi ho finito con il seguente comando:

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

Ciò che fa comunque, è copiare tutti i file dalla nuova alla differenza , anche quelli che sono gli stessi della vecchia .

Nel caso in cui aiuti (forse il comando va bene e l'errore sta altrove), è così che ho provato questo:

  1. Ho creato le tre cartelle.
  2. Ho creato diversi file di testo con diversi contenuti in vecchio .
  3. Ho copiato i file dal vecchio al nuovo .
  4. Ho modificato il contenuto di alcuni dei file in nuovi e ho aggiunto alcuni file aggiuntivi.
  5. Ho eseguito il comando sopra e verificato i risultati in differenza .

Ho cercato una soluzione negli ultimi due giorni e apprezzerei molto l'aiuto. Non deve necessariamente usare rsync, ma mi piacerebbe sapere cosa sto facendo di sbagliato, se possibile.



@wingedsubmariner Non credo che sia un duplicato, poiché la risposta accettata alla domanda collegata è il comando a cui l'OP sta ponendo una domanda.
Bernhard,

@ Bernhard Ah, il mio male. Immagino di aver frainteso la domanda originale.
Wingedsubmariner,

@wingedsubmariner Nessun problema, hai detto "possibile", e concordo che sembra molto simile :)
Bernhard

Risposte:


7

Non sono sicuro che sia possibile farlo con qualsiasi comando linux esistente come rsync o diff. Ma nel mio caso ho dovuto scrivere il mio script usando Python, poiché python ha il modulo "filecmp" per il confronto dei file. Ho pubblicato l'intero script e l'utilizzo nel mio sito personale - http://linuxfreelancer.com/

L'utilizzo è semplice: assegnagli il percorso assoluto della nuova directory, della directory precedente e della directory delle differenze in questo ordine.

#!/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()

21

Ho capito quale fosse il problema nel mio caso:

I file che stavo confrontando avevano diversi timestamp. Non avrei dovuto usare l' argomento -a , presumo perché rsync stava cercando di preservare i timestamp durante la copia dei file. Il comando che ha funzionato per me è stato:

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

Penso di provarlo con l'opzione -a (archivio), avresti dovuto usare rsync -aper "copiare" i file inizialmente (o l'equivalente in cp), quindi cancellati o modificati. (Mi piace attenermi a rsync perché so che è auto-coerente senza pensare a cosa potrebbe fare.) Penso che avrebbe dovuto funzionare con il comando originale. L'opzione -a include -t (confronta per timestamp), che è l'alternativa a -c (confronta per checksum).
Salvia,

2
Secondo me, questa risposta dovrebbe essere quella accettata, poiché è molto più semplice. Inoltre, il comando ha funzionato solo per me quando ho fornito il percorso completo per old/e new/.
Yamaneko,

L'avvertenza sembra essere che il confronto-dest debba essere il percorso relativo alla differenza visto dall'interno del dest reale
Ryan Williams

1

Ciò potrebbe aiutare alcuni lettori: in Windows, un vecchio programma freeware, Third Dir, fa esattamente ciò che viene richiesto qui. Non è più disponibile tramite lo sviluppatore, Robert Vašíček. Ma sono sicuro che può essere trovato tramite alcuni repository online.

Ecco la descrizione dello sviluppatore, che rimane sul suo sito:

Terza directory: un insolito sincronizzatore di directory: i diversi file vengono copiati nella terza directory. È molto utile estrarre, ad esempio, foto nuove o modificate da un enorme albero di directory su disco fisso in una cartella temporanea, quindi aggiungerle al CD di archiviazione (nota: i file originali vengono confrontati con il CD). Versione 1.4, dimensione 23kB. Creato il 12-02-2005.

Cronologia: Versione 1.14 - Più efficiente quando vengono confrontate molte decine di migliaia di file.


0

Il modo rsync dato da Thane con le aggiunte di Yamaneko funziona alla grande ma lascia directory vuote. Per me la soluzione finale è stata in due passaggi, prima chiama rsync con il percorso completo, quindi un comando find per rimuovere tutte le directory vuote:

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

Nota che anche con l'opzione --links, rsync non ha conservato i collegamenti simbolici ma ha copiato i dati di destinazione.


Nota che invece di -empty -exec rmdir {} \;te puoi usare -empty -delete.
lunedì

-3

Uso il dualpane XY Explorer (commerciale), che può fare molti trucchi e questo è uno di questi. Apri Currentin un riquadro e Vecchio nell'altro. Attiva il riquadro corrente. Vai a Riquadri > Seleziona sincronizzazione . Ti offre 5 opzioni per selezionare:

  1. Partite (elencate in entrambi)
  2. Uniques (nel riquadro attivo)
  3. Più recente (nel riquadro attivo)
  4. File univoci e più recenti (nel riquadro attivo)
  5. Selezionato (quelli selezionati nell'altro riquadro)

Ora puoi copiare la selezione risultante da Currentdove vuoi. L'ho usato per confrontare mailfoldersdalle vecchie installazioni con le ultime. La struttura delle cartelle era piuttosto complessa, ma (quasi) tutti mbs-filesavevano un numero univoco.

Quindi ho fatto una ricerca mbs-filesnella vecchia radice mailfolder(in un riquadro) e anche nella più recente (nell'altro riquadro) e ho fatto un confronto sui risultati della ricerca in ciascun riquadro ( Sincronizza Seleziona univoco , per trovare i messaggi mancanti durante ri-installazioni)! Puoi anche impostare molte opzioni.


1
Se stai parlando di software non standard, dovresti includere un link. Se intendi XYplorer che non aiuterà affatto l'OP.
Anthon,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.