撤消复制 (cp) 命令操作

撤消复制 (cp) 命令操作

我使用终端中的以下命令行将一些文件从源文件夹复制到目标文件夹。

sudo cp From_SOURCE/* To_DESTINATION/

现在我想撤消这个命令。

答案1

如果我理解正确的话,情况如下:

  • 您已将大量文件复制到现有目录中,并且需要/想要撤消该操作。
  • 目标目录包含许多其他文件,你需要保留在那里,这使得无法简单地删除全部目录中的文件

下面的脚本会查看原始(源)目录并列出这些文件。然后,它会查看您将文件复制到的目录,并仅删除列出的文件(因为它们存在于源目录中)。

添加该try元素是为了防止出现错误,例如,如果您可能已经手动删除了一些文件,或者源目录中并非所有文件都已复制到目标目录。如果您需要 sudo 权限,只需使用“sudo”运行脚本即可(见下文)。

剧本

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

如何使用

  • 将脚本粘贴到空文件中,并将其另存为reverse.py
  • 插入源文件夹和目标文件夹的正确路径,
  • 为了方便起见,使其可执行,
  • 通过命令运行:

    [sudo] /path/to/reverse.py
    

警告

如果我清楚了解您需要实现的目标,请首先尝试测试目录!


如果源目录是“平面”

如果源目录没有子目录,脚本可以更简单:

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

笔记

如果复制操作覆写(替换)目标中名称相似的文件,则该文件将被删除,但脚本不会恢复原始文件(当然)。假设没有名称冲突。

答案2

总结:

两者中存在的所有文件都src可以像这样dest删除:dest

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

有关分步解释,请参见下文。

简化问题:

为了理解我们要撤消的命令实际上做了什么,我们首先简化它:

我们要撤消的命令是

sudo cp From_SOURCE/* To_DESTINATION/

对于了解如何撤消,sudo并不相关。

我将使用目录名src和。From_SOURCEdestTo_DESTINATION

现在,我们的命令是:

cp src/* dest/

如果src包含文件f1f2f3,以及目录d1d2,则 shell 将该命令扩展为:

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

-r如果没有、-R或等选项-a,该命令cp不会复制目录。
这意味着,该命令将忽略它们,并为每个目录显示一个错误:

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

这意味着,我们仅复制了简单文件,而没有复制目录dest

决定删除哪些文件:

中可能存在dest与 中的文件同名的文件src。在这种情况下,文件被覆盖 (1)。很抱歉,对他们来说已经太晚了。从最新备份中恢复它们。

对于存在的文件,我们只想删除已复制的文件。这些文件存在于两个目录中,具有相同的名称和相同的内容。

因此我们寻找这些文件:

首先,我们cd进入src,因为它使以下find命令变得更简单,并将变量设置为dest的绝对路径:

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

然后,我们列出src中的所有文件:

$ find . -maxdepth 1 -type f

并且,对于找到的每个文件,用来cmp检查目标中是否存在具有相同内容的文件:

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

小心地删除文件:

这些文件就是我们要删除的文件。但为了确保万无一失,我们先将它们移到另一个目录中 - 并在运行它们之前查看命令:

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

看起来不错!现在我们可以省略echo运行真正的mv命令:

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

dest从复制的所有文件,并且实际上在和src中仍然相同,现在位于 中,并且在最后查看一次后可以将其删除。srcdest/tmp/toDelete/


注意:
(1)检查是否cp是左右的别名cp -i,这样可以通过先询问来防止覆盖文件。

答案3

这已经很老了,但我只是想发布一个纯 bash 答案:

首先更改到您复制文件的目录。

cd dest

然后,ls将源目录和输出导入到rm

ls source | xargs rm

答案4

这是基于复制操作的时间戳的答案。您可以按创建时间顺序列出文件夹内容并将其传送到文件:

ls -alt | file_list

然后打开file_list并找到与复制操作时间戳相同的文件。 推测这些将是最新的文件。

然后编辑file_list不需要rm -rf的文件/文件夹并保存。

然后做:

source file_list

相关内容