TL; DR:
Tutti i file presenti in entrambi src
e che dest
possono essere rimossi da dest
questo:
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, sudo
non è rilevante.
Userò i nomi delle directory src
per From_SOURCE
e dest
per To_DESTINATION
.
Ora, il nostro comando è:
cp src/* dest/
Se src
contiene i file f1
, f2
ef3
, e le directory d1
e d2
, la shell espande quel comando a:
cp src/f1 src/f2 src/f3 src/d1 src/d2 dest/
Senza opzioni come -r
, -R
o -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, cd
in src
, perché rende i seguenti find
comandi 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 cmp
per 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 echo
di eseguire i mv
comandi reali :
find . -maxdepth 1 -type f -exec cmp -s '{}' "$destdir/{}" \; -exec mv -n "$destdir/{}" "$toDelete"/ \;
Tutti i file da dest
cui sono stati copiati src
, e in realtà sono sempre gli stessi in src
e dest
, sono ora in /tmp/toDelete/
e possono essere rimossi dopo aver dato un ultimo sguardo.
Note:
(1) Controlla se cp
è un alias cp -i
o giù di lì, che avrebbe impedito la sovrascrittura dei file chiedendo prima.