如何递归比较两个文件夹并生成不同的文件和文件夹列表?

如何递归比较两个文件夹并生成不同的文件和文件夹列表?

总结和一个例子

我正在寻找一种方法来递归比较两个文件夹并输出所有不同的文件(和文件夹)的相对路径(按大小或时间戳,à la rsync)。

例如,假设我有

C:\source\foo\a.txt
C:\source\foo\bar\b.txt
C:\source\foo\bar\c.txt

C:\target\foo\a.txt
C:\target\foo\bar\b.txt
C:\target\foo\bar\d.txt
C:\target\foo\baz\

并且假设b.txt已在下更改C:\source,因此更新。

然后给出一个神奇的脚本或命令,比如magic C:\source C:\target,我希望输出是

foo\bar\b.txt

或者,源文件夹或目标文件夹的完整路径也是可以接受的:

C:\source\foo\bar\b.txt

正如示例所示,我不关心已被删除或创建的文件和文件夹!这应该会使这个任务比其他任务简单得多。

我已经知道了……

我自己就是一名 UNIX 开发人员,如果我们处理的是 UNIX 系统,我不会问这个问题,但很遗憾。此外,这是一个自定义的夜间备份解决方案,可靠性和数据完整性是首要任务,因此考虑到几周前我甚至无法弄清楚批处理脚本中的 for 循环,我确信我缺乏正确执行此操作的经验,甚至无法确定执行此操作的最佳方法。

阅读http://www.howtoforge.com/backing-up-with-rsync-and-managing-previous-versions-history我了解到 rsync 可以做我想做的事情,使用如下选项

--dry-run               # don't actually rsync (touch) any files
--itemize-changes       # list changes rsync _would_ have made
--out-format="%i|%n|"   # define an output format for the list of changes

但是,我不愿意依赖 Cygwin (cwRsync) 来使用 rsync,因为我已经习惯在 Cygwin 安装上运行快速而粗糙的实验,经常破坏环境,并且每隔几周就需要重新安装 Cygwin。这有点违背了夜间备份的“可靠性”部分。

我还没有在 Windows 中找到任何像 rsync 这样的“规范”工具,至少没有找到任何支持上述选项的工具。此外,我不是在寻找软件一般来说,除非它是一个专门用于此目的的简单而紧凑的工具——我更喜欢透明的、程序化的解决方案。对于备份文件这样重要的事情,依赖我看不见或看不懂的软件或代码是件很可怕的事!

回顾

我无法理解批处理脚本语法。接下来我将尝试 PowerShell。但是完成这个任务后我应该做什么?——我是否遗漏了一些明显的路线?

答案1

@Glytzhkof 在他的回答中推荐了 Robocopy,它完全满足了我的需求。

总结

C:\>robocopy.exe source target /l /e /zb /xx /xl /fp /ns /nc /ndl /np /njh /njs

                                C:\source\foo\bar\b.txt

选项详情及说明

Robocopy(维基百科)似乎被广泛用于 Windows 系统管理;有据可查(TechNet);被讨论为不仅仅是一个模糊的堆栈溢出服务器故障当然,这里超级用户; 提供特定功能,而不是试图成为多用途工具(这容易导致臃肿和错误);而且自 1997 年以来一直提供此特定功能。对我来说,尽管它是闭源的,但所有这些因素都有助于实现“透明度”,让我安心。

Robocopy 是目前称为Windows Server 2003 资源工具包工具下载并安装后,我重新创建了问题中的场景并尝试了一下:

C:\>robocopy.exe source target /l /e /zb

-------------------------------------------------------------------------------
   ROBOCOPY     ::     Robust File Copy for Windows
-------------------------------------------------------------------------------

  Started : Thu May 01 09:08:20 2014

   Source : C:\source\
     Dest : C:\target\

    Files : *.*

  Options : *.* /L /S /E /COPY:DAT /ZB /R:1000000 /W:30

------------------------------------------------------------------------------

                           0    C:\source\
                           1    C:\source\foo\
        *EXTRA Dir        -1    C:\target\foo\baz\
                           2    C:\source\foo\bar\
          *EXTRA File                  1        d.txt
            Newer                      5        b.txt
            New File                   1        c.txt

------------------------------------------------------------------------------

               Total    Copied   Skipped  Mismatch    FAILED    Extras
    Dirs :         3         0         3         0         0         1
   Files :         3         2         1         0         0         1
   Bytes :         7         6         1         0         0         1
   Times :   0:00:00   0:00:00                       0:00:00   0:00:00

   Ended : Thu May 01 09:08:20 2014

看起来不错!让我解释一下这些选项:

  • /l列出动作没有真正地去执行它们。
  • /e包括子目录,但与不同的是/s,它还包括空目录。
  • /zb在“重启”模式下复制,在访问被拒绝时,使用“备份”模式;这似乎是最安全的方法;阅读更多这里

由于我实际上没有执行任何操作,因此我不需要任何与复制相关的选项。

无论如何,接下来只需添加更多开关即可获得我想要的输出:

C:\>robocopy.exe source target /l /e /zb /xx /xl /fp /ns /nc /ndl /np /njh /njs

                                C:\source\foo\bar\b.txt

再次,让我们看一下这些选项。

首先,我只关心修改的文件和文件夹,因此:

  • /xx排除“额外”的文件和目录——仅存在于目标中的文件和目录。
  • /xl排除“孤独”的文件和目录——那些仅存在于源中的文件和目录。

其次,我需要相对路径(或者至少是完整路径,而不仅仅是名称):

  • /fp启用完整路径(毫不奇怪,没有相对路径选项)。

第三,我想尽可能多地去除木材上的绒毛,结果我惊喜地发现全部其中之一是可拆卸的:

  • /ns抑制文件大小。
  • /nc压制阶级,例如 Newer
  • /ndl抑制目录名称。
  • /np抑制复制进度输出。
  • /njh抑制作业头。
  • /njs禁止显示工作概要。

就这样!


就我的目的而言(创建已更改文件的版本备份),我意识到我实际上也希望拥有每个已修改文件的时间戳。只需添加/ts

C:\>robocopy.exe source target /l /e /zb /xx /xl /fp /ns /nc /ndl /np /njh /njs /ts

                         2014/05/01 15:20:42    C:\source\foo\bar\b.txt

答案2

我曾经制作过一个自定义的批处理驱动备份系统,该系统有一个第三方工具,每晚将新文件和更改的文件复制到备份驱动器。我一时想不起那个工具的名字了。我可能能找到它,但现在不行。

最好的廉价商业比较工具是无可比拟http://www.scootersoftware.com/- 毫无疑问,它是一款出色的工具。它的作用立竿见影,是所有每天处理文件的专业人士都会受益的工具。尝试一下查看屏幕截图包含命令行版本

除此之外复制工具只要耐心并经过测试,就应该能够完成您想要的事情。

另一个提示:为了避免备份灾难,我使用低权限帐户运行备份脚本,以防止如果有人弄乱脚本,或者如果有人试图用它登录,它不会删除任何内容。我想我将帐户设置为非交互式或无法以交互方式登录或类似情况。强烈建议在 Windows 上批量运行此操作。我只是想提一下,因为你来自 Unix 世界。

答案3

我不愿意依赖 Cygwin (cwRsync) 来使用 rsync

可以将 rsync 与 Windows Subsystem for Linux (WSL) 一起使用,也可以与适用于 Windows 的 Git要在 Windows 上使用 rsync 与 Git,可以按照以下步骤操作脚步

你可以 点击这里 查找并下载 Rsync,然后使用 規模 来提取它(通过在 Git Bash 中运行命令)。 

下一步是将解压的文件移动到相应的目标位置。例如:

  • \\rsync-3.2.2-1\\usr\\bin → C:\\Program Files\\Git\\usr\\bin
  • \\rsync-3.2.2-1\\usr\\lib → C:\\Program Files\\Git\\usr\\lib
  • \\rsync-3.2.2-1\\usr\\share → C:\\Program Files\\Git\\usr\\share

然后您应该能够通过 Git Bash 在 Windows 10 中使用 Rsync 命令。

相关内容