TL; DR:
Todos los archivos que están presentes en ambos srcy destse pueden eliminar de destesta manera:
find . -maxdepth 1 -type f -exec cmp -s '{}' "$destdir/{}" \; -exec mv -n "$destdir/{}" "$toDelete"/ \;
Para una explicación paso a paso, ver más abajo.
Simplificando el problema:
Para comprender qué hizo realmente el comando que queremos deshacer, comenzamos por simplificarlo:
El comando que queremos deshacer es
sudo cp From_SOURCE/* To_DESTINATION/
Para entender cómo deshacer, sudono es relevante.
Usaré los nombres de directorio srcpara From_SOURCEy destpara To_DESTINATION.
Ahora, nuestro comando es:
cp src/* dest/
Si srccontiene los archivos f1, f2y f3, y los directorios d1y d2, el shell expande ese comando para:
cp src/f1 src/f2 src/f3 src/d1 src/d2 dest/
Sin opciones como -r, -Ro -a, el comando cpno copia directorios.
Eso significa que el comando los dejará fuera, mostrando un error para cada uno de ellos:
$ cp src/f1 src/f2 src/f3 src/d1 src/d2 dest/
cp: omitting directory 'src/d1'
cp: omitting directory 'src/d2'
Eso significa que solo hemos copiado archivos simples, y no directorios, a dest.
Decidir qué archivos eliminar:
Posiblemente había archivos con destel mismo nombre que los archivos src. En este caso, los archivos se sobrescribieron (1). Es demasiado tarde para ellos, lo siento. Recuperarlos de la última copia de seguridad.
Con respecto a los archivos que están allí, queremos eliminar solo los archivos que se han copiado. Estos archivos existen en ambos directorios, con el mismo nombre y el mismo contenido.
Entonces buscamos estos archivos:
En primer lugar, cden src, porque hace que los siguientes findcomandos mucho más simples, y establecer una variable en la ruta absoluta del dest:
$ cd src
$ destdir="$(readlink -f dest)"
Luego, enumeramos todos los archivos en src:
$ find . -maxdepth 1 -type f
y, para cada archivo encontrado, use cmppara verificar si hay un archivo con el mismo contenido en dest:
$ find . -maxdepth 1 -type f -exec cmp -s '{}' "$destdir/{}" \; -print
Eliminando los archivos, cuidadosamente:
Estos archivos son los que queremos eliminar. Pero para estar seguros, primero los movemos a un directorio diferente, y echamos un vistazo a los comandos antes de ejecutarlos:
$ 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/`
¡Se ve bien! Ahora podemos dejar echode ejecutar los mvcomandos reales :
find . -maxdepth 1 -type f -exec cmp -s '{}' "$destdir/{}" \; -exec mv -n "$destdir/{}" "$toDelete"/ \;
Todos los archivos desde destque fueron copiados de src, y todavía en realidad la misma en srcy dest, ahora están en /tmp/toDelete/, y pueden ser removidos después de tomar una última mirada.
Notas:
(1) Verifique si cpes un alias cp -io no, eso habría evitado sobrescribir archivos preguntando primero.