总结和一个例子
我正在寻找一种方法来递归比较两个文件夹并输出所有不同的文件(和文件夹)的相对路径(按大小或时间戳,à 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 命令。