Deshacer la acción del comando copiar (cp)

Deshacer la acción del comando copiar (cp)

Copié un archivo de la carpeta de origen a la carpeta de destino usando la siguiente línea de comando en la terminal.

sudo cp From_SOURCE/* To_DESTINATION/

Ahora quiero deshacer este comando.

Respuesta1

Si entiendo bien, el caso es el siguiente:

  • Copiaste una cantidad (presumiblemente grande) de archivos en un directorio existente y necesitas o deseas revertir la acción.
  • El directorio de destino contiene una serie deotroarchivos, que debe mantener allí, lo que hace que sea imposible simplemente eliminarlostodoarchivos del directorio

El siguiente script busca en el directorio original (fuente) y enumera esos archivos. Luego busca en el directorio en el que copió los archivos y elimina solo los archivos enumerados, tal como existen en el directorio de origen.

El tryelemento se agrega para evitar errores, por ejemplo, en caso de que ya haya eliminado algunos archivos manualmente o si no todos los archivos del directorio de origen se copiaron en el destino. Si necesita privilegios de sudo, simplemente ejecute el script con "sudo" (ver más abajo).

La secuencia de comandos

#!/usr/bin/env python

import os

source_dir = "/path/to/source" # the folder you copied the files from
target_folder = "/path/to/destination" # the folder you copied the files to

for root, dirs, files in os.walk(source_dir):
    for name in files:
        try:
            os.remove(target_folder+"/"+name)
        except FileNotFoundError:
            pass

Cómo utilizar

  • Pegue el script en un archivo vacío, guárdelo como reverse.py,
  • Inserte las rutas correctas para la carpeta de origen y de destino,
  • Hazlo ejecutable por razones de conveniencia,
  • Ejecútelo con el comando:

    [sudo] /path/to/reverse.py
    

Advertencia

¡Primero pruebe con un directorio de prueba si entendí bien lo que necesita lograr!


Si el directorio de origen es "plano"

En caso de que el directorio fuente no tenga subdirectorios, el script puede ser incluso más simple:

#!/usr/bin/env python

import os

source_dir = "/path/to/source" # the folder you copied the files from
target_folder = "/path/to/destination" # the folder you copied the files to

for file in os.listdir(source_dir):
    try:
        os.remove(target_folder+"/"+file)
    except FileNotFoundError:
        pass

Nota

Si la acción de copiarsobrescrito(reemplazado) un archivo con un nombre similar en el destino, el archivo se eliminará, pero el script (por supuesto) no recuperará el archivo original. Se supone que no hay conflictos de nombres.

Respuesta2

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 obtener una explicación paso a paso, consulte a continuación.

Simplificando el problema:

Para entender qué hizo realmente el comando que queremos deshacer, comenzamos simplificándolo:

El comando que queremos deshacer es

sudo cp From_SOURCE/* To_DESTINATION/

Para entender cómo deshacer,sudo no es relevante.

Usaré los nombres de directorio srcpara From_SOURCEy destparaTo_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 a:

cp src/f1 src/f2 src/f3 src/d1 src/d2 dest/

Sin opciones como -ro -R, -ael comando cpno copia directorios.
Es decir, el comando los omitirá, 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 sólo hemos copiado archivos simples, y ningún directorio, adest .

Decidir qué archivos eliminar:

Posiblemente había archivos con destel mismo nombre que los archivos ensrc . En este caso, los archivos fueron sobrescritos (1). Es demasiado tarde para ellos, lo siento. Recupérelos desde la última copia de seguridad.

Con respecto a los archivos que están allí, queremos eliminar sólo los archivos que se han copiado. Estos archivos existen en ambos directorios, con el mismo nombre y el mismo contenido.

Entonces buscamos estos archivos:

Primero, cdingresamos src, porque hace que los siguientes findcomandos sean mucho más simples y establecemos una variable en la ruta absoluta de destino:

$ 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

Quitando los archivos, con cuidado:

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 omitir el echopara ejecutar los comandos reales mv:

find . -maxdepth 1 -type f -exec cmp -s '{}' "$destdir/{}" \; -exec mv -n "$destdir/{}" "$toDelete"/ \;

Todos los archivos destque se copiaron de src, y en realidad siguen siendo los mismos en srcy dest, ahora están en /tmp/toDelete/y se pueden eliminar después de echar un último vistazo.


Notas:
(1) Compruebe si cpes un alias cp -io algo así que habría impedido sobrescribir archivos preguntando primero.

Respuesta3

Esto es antiguo, pero solo quería publicar una respuesta bash pura:

Primero cambie al directorio donde copió los archivos.

cd dest

Luego, lsel directorio de origen y canaliza la salida arm

ls source | xargs rm

Respuesta4

Esta es una respuesta basada en la marca de tiempo de la operación de copia. Puede enumerar el contenido de la carpeta en orden de tiempo de creación y canalizarlo a un archivo:

ls -alt | file_list

Luego abra file_listy busque los archivos con la misma marca de tiempo de las operaciones de copia. Presumiblemente, estos serán los archivos más recientes.

Luego edítelo file_listen rm -rflos archivos/carpetas no necesarios y guárdelo.

Entonces hazlo:

source file_list

información relacionada