我有 2 个包含文件的文件夹。这些文件是某些构建过程的产物。第一个文件夹是先前的版本而后者是当前版本。
我想以某种方式从命令行/构建脚本中区分这两个文件夹并复制仅限已添加的文件或将新文件放入其他文件夹中。
例如:
**FOLDER1** (new build)
a.txt
b.txt (modified)
c.txt
d.txt
**FOLDER2** (prev build)
a.txt
b.txt
c.txt
基于此,我感兴趣的复制操作将仅将 b.txt 和 d.txt 复制到其他文件夹中(而不是复制到 folder2 中)。
基本上,我只是在寻找“增量”,并且想将它们存储在某个地方。
使用 Windows 自带的标准命令行工具可以实现这一点吗?(假设是 Windows 7/Server 2008 或更高版本)
答案1
使用带有 /D 和 /L 选项的 XCOPY,从文件夹 1“复制”到文件夹 2。
/D 选项将复制限制为仅新的或修改过的文件。
/L 选项使命令列出要复制的文件,但阻止实际进行任何复制。
然后使用 FOR /F 处理这些结果并将文件实际复制到文件夹 3。
for /f "eol=: delims=" %F in ('xcopy /dl "folder1\*" "folder2"') do @copy "%F" "f3" >nul
如果放入批处理文件中,则所有内容都%
必须加倍为%%
。
XCOPY 还会打印出受影响文件数量的摘要。上述命令将尝试复制摘要计数为“name”的文件,当然会失败。将输出重定向到 nul 可防止显示错误消息。我在 Windows 7 上进行了测试,结果让我很惊讶错误消息出现在 stdout 上,而不是 stderr 上。如果其他版本上的错误消息出现在 stderr 上,则该命令还应获取 2>nul 以防止显示错误消息。
但隐藏错误信息存在风险——如果复制由于某种原因失败怎么办?
下面是一个脚本,它将列出所有成功复制的文件,并指出哪些文件(如果有)复制失败。它使用 FINDSTR 过滤掉不需要的文件数。它假设文件数是英文的,格式为NNN File(s)
,因此必须针对其他语言进行修改。
@echo off
for /f "eol=: delims=" %%F in (
'xcopy /dl "folder1\*" "folder2" ^| findstr /v "^[0-9][0-9]* File(s)"'
) do copy "%%F" "folder3" >nul && echo "%%F"|| echo FAILED: "%%f"
这是一个更复杂的变体,适用于任何语言。它将每个文件名保存到变量中,并将复制延迟到下一次循环迭代。最后一个条目(计数)永远不会被复制。
@echo off
setlocal disableDelayedExpansion
set "file="
for /f "eol=: delims=" %%F in ('xcopy /dl "folder1\*" "folder2"') do (
if defined file (
setlocal enableDelayedExpansion
copy "!file!" "folder3" >nul && echo "!file!" || echo FAILED: "!file!"
endlocal
)
set "file=%%F"
)
答案2
我更喜欢 ROBOCOPY。使用 XCOPY 多年后发现需要在缓慢/不稳定的互联网连接上重新启动复制操作。
ROBOCOPY 源目标/s/e/xo
或镜子
ROBOCOPY 源目标/mir
使用日志选项获取您的列表以供稍后检查。
ROBOCOPY 源目标/s/e/xo/log:文件