TL; DR:
Tutti i file presenti in entrambi srce che destpossono essere rimossi da destquesto:
find . -maxdepth 1 -type f -exec cmp -s '{}' "$destdir/{}" \; -exec mv -n "$destdir/{}" "$toDelete"/ \;
Per una spiegazione dettagliata, vedere di seguito.
Semplificare il problema:
Per capire cosa ha effettivamente fatto il comando che vogliamo annullare, iniziamo semplificandolo:
Il comando che vogliamo annullare è
sudo cp From_SOURCE/* To_DESTINATION/
Per capire come annullare, sudonon è rilevante.
Userò i nomi delle directory srcper From_SOURCEe destper To_DESTINATION.
Ora, il nostro comando è:
cp src/* dest/
Se srccontiene i file f1, f2ef3 , e le directory d1e d2, la shell espande quel comando a:
cp src/f1 src/f2 src/f3 src/d1 src/d2 dest/
Senza opzioni come -r, -Ro -a, il comandocp non copia le directory.
Ciò significa che il comando li lascerà fuori, mostrando un errore per ciascuno di essi:
$ cp src/f1 src/f2 src/f3 src/d1 src/d2 dest/
cp: omitting directory 'src/d1'
cp: omitting directory 'src/d2'
Ciò significa che abbiamo copiato solo file semplici e nessuna directory dest.
Decidere quali file rimuovere:
Forse c'erano dei file dest lo stesso nome dei file in src. In questo caso, i file sono stati sovrascritti (1). È troppo tardi per loro, scusa. Riportali dall'ultimo backup.
Per quanto riguarda i file presenti, vogliamo rimuovere solo i file che sono stati copiati. Questi file esistono in entrambe le directory, con lo stesso nome e lo stesso contenuto.
Quindi cerchiamo questi file:
In primo luogo, cdin src, perché rende i seguenti findcomandi molto più semplici, e impostare una variabile per il percorso assoluto della dest:
$ cd src
$ destdir="$(readlink -f dest)"
Quindi, elenchiamo tutti i file in src:
$ find . -maxdepth 1 -type f
e, per ogni file trovato, utilizzare cmpper verificare se esiste un file con lo stesso contenuto in dest:
$ find . -maxdepth 1 -type f -exec cmp -s '{}' "$destdir/{}" \; -print
Rimozione dei file, con attenzione:
Questi file sono quelli che vogliamo rimuovere. Ma per sicurezza, li spostiamo prima in una directory diversa - e diamo un'occhiata ai comandi prima di eseguirli:
$ toDelete=/tmp/toDelete ; mkdir -p "$toDelete"
$ find . -maxdepth 1 -type f -exec cmp -s '{}' "$destdir/{}" \; -exec echo mv -n "$destdir/{}" "$toDelete"/ \;
mv -n /path/to/dest/./f1 /tmp/toDelete/`
mv -n /path/to/dest/./f2 /tmp/toDelete/`
mv -n /path/to/dest/./f3 /tmp/toDelete/`
Sembra buono! Ora possiamo tralasciare echodi eseguire i mvcomandi reali :
find . -maxdepth 1 -type f -exec cmp -s '{}' "$destdir/{}" \; -exec mv -n "$destdir/{}" "$toDelete"/ \;
Tutti i file da destcui sono stati copiati src, e in realtà sono sempre gli stessi in srce dest, sono ora in /tmp/toDelete/e possono essere rimossi dopo aver dato un ultimo sguardo.
Note:
(1) Controlla se cpè un alias cp -io giù di lì, che avrebbe impedito la sovrascrittura dei file chiedendo prima.