web-dev-qa-db-fra.com

Action de commande Annuler copie (cp)

J'ai copié un fichier du dossier source dans le dossier de destination en utilisant la ligne de commande ci-dessous dans le terminal.

Sudo cp From_SOURCE/* To_DESTINATION/

Maintenant, je veux annuler cette commande.

13
αғsнιη

Si je comprends bien, voici le cas:

  • Vous avez copié un nombre (probablement grand) de fichiers dans un répertoire existant et vous devez/souhaitez inverser l'action.
  • Le répertoire ciblé contient un certain nombre de autres fichiers que vous devez conserver, ce qui rend impossible toute suppression tous les fichiers du répertoire

Le script ci-dessous cherche dans le répertoire d'origine (source) et répertorie ces fichiers. Ensuite, il examine le répertoire dans lequel vous avez copié les fichiers et ne supprime que les fichiers répertoriés, tels qu'ils existent dans le répertoire source.

L'élément try est ajouté pour éviter les erreurs, par exemple dans le cas où vous auriez peut-être déjà supprimé certains fichiers manuellement, ou si tous les fichiers du répertoire source n'ont pas été copiés dans la destination. Si vous avez besoin des privilèges Sudo, exécutez simplement le script avec "Sudo" (voir ci-dessous).

Le scénario

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

Comment utiliser

  • Collez le script dans un fichier vide, enregistrez-le sous le nom reverse.py,
  • Insérez les chemins corrects pour le dossier source et cible,
  • Rendez-le exécutable pour des raisons de commodité,
  • Exécutez-le à l'aide de la commande:

    [Sudo] /path/to/reverse.py
    

Attention

Commencez par essayer un répertoire de test si j'ai bien compris ce que vous devez accomplir!


Si le répertoire source est "flat"

Si le répertoire source n'a pas de sous-répertoires, le script peut même être plus 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

Note

Si l'action de copie a écrasé (remplacé) un fichier portant le même nom dans la destination, le fichier sera supprimé, mais le fichier d'origine ne (bien sûr) pas être rapporté par le script. L'hypothèse est qu'il n'y a pas de conflits de noms.

13
Jacob Vlijm

TL; DR:

Tous les fichiers présents dans src et dest peuvent être supprimés de dest comme ceci:

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

Pour une explication pas à pas, voir ci-dessous.

Simplifier le problème:

Pour comprendre ce que la commande que nous voulons annuler a réellement effectuée, commençons par la simplifier:

La commande que nous voulons annuler est

Sudo cp From_SOURCE/* To_DESTINATION/

Pour comprendre comment annuler, Sudo n'est pas pertinent.

J'utiliserai les noms de répertoire src pour From_SOURCE et dest pour To_DESTINATION.

Maintenant, notre commande est:

cp src/* dest/

Si src contient les fichiers f1, f2 et f3 et les répertoires d1 et d2, le shell développe cette commande pour:

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

Sans options telles que -r, -R ou -a, la commande cp ne copie pas les répertoires.
Cela signifie que la commande les laissera de côté en indiquant une erreur pour chacun d’eux:

$ cp src/f1 src/f2 src/f3 src/d1 src/d2 dest/
cp: omitting directory 'src/d1'
cp: omitting directory 'src/d2'

Cela signifie que nous n’avons copié que des fichiers simples, et aucun répertoire, dans dest.

Décider des fichiers à supprimer:

Il se peut qu'il y ait des fichiers dans dest du même nom que des fichiers dans src. Dans ce cas, les fichiers ont été écrasés (1). C'est trop tard pour eux, désolé. Récupérez-les à partir de la dernière sauvegarde.

En ce qui concerne les fichiers présents, nous souhaitons supprimer uniquement les fichiers copiés. Ces fichiers existent dans les deux répertoires, avec le même nom et le même contenu.

Nous cherchons donc ces fichiers:

Tout d’abord, cd dans src, car il simplifie beaucoup les commandes find suivantes et définit une variable sur le chemin absolu de dest:

$ cd src
$ destdir="$(readlink -f dest)"

Ensuite, nous listons tous les fichiers dans src:

$ find . -maxdepth 1 -type f

et, pour chaque fichier trouvé, utilisez cmp pour vérifier s'il existe un fichier ayant le même contenu dans dest:

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

En supprimant les fichiers, soigneusement:

Ces fichiers sont ceux que nous voulons supprimer. Mais pour être sûr, nous les déplaçons d'abord dans un répertoire différent - et jetons un coup d'œil aux commandes avant de les exécuter:

$ 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/`

Cela semble bon! Nous pouvons maintenant laisser de côté le echo pour exécuter les vraies commandes mv:

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

Tous les fichiers de dest qui ont été copiés à partir de src et qui sont en réalité les mêmes dans src et dest sont maintenant dans /tmp/toDelete/ et peuvent être supprimés après un dernier examen.


Remarques:
(1) Vérifiez si cp est un alias de cp -i ou du type qui aurait pu empêcher l’écrasement des fichiers en demandant d’abord.

7
Volker Siegel

C'est vieux, mais je voulais juste poster une réponse pure bash:

Commencez par accéder au répertoire où vous avez copié les fichiers.

cd dest

Ensuite, ls le répertoire source et dirigez la sortie vers rm

ls source | xargs rm

5
Michael Goldstein