如果不存在,如何将更新的文件复制到新文件夹并创建目录作为源?

how to copy updated files to new folder and create directory as source if not exist?

我试图比较 2 个文件夹中的文件,并将这些新文件和更新后的文件复制到 diff 文件夹,例如:

newFolder has  
a\aa.txt (new folder and new file)  
b\aa.txt  
b\ab.exe (modified)  
b\ac.config (new file)  
aa.txt (modified)  
ab.exe (new file)  
ac.config

oldFolder has  
b\aa.txt  
b\ab.exe  
aa.txt  
ac.config

在这种情况下,我希望 diff 文件夹中的内容应该是:

diffFolder    
a\aa.txt  
b\ab.exe  
b\ac.config  
aa.txt  
ab.exe

到目前为止,我一直在 google 上搜索并尝试了不同的方法,但仍然无法实现。
我得到的文件列表包括需要使用
复制的文件及其路径 xcopy /edyl "newFolder\*" "oldFolder"
并尝试使用

for /f %%F in ('xcopy /e /dyl "new\*" "old"') do @xcopy %%F diff /e

这会弄乱 diffFolder
也试过

for /f %%F in ('xcopy /e /dyl "new\*" "old"') do @robocopy new diff %%F /e

这只会在 diffFolder 中创建目录但不会复制文件,给我错误:无效参数 #3 :"newFolder\a\aa.txt"

for /f %%F in ('xcopy /e /dyl "new\*" "old"') do @copy "%%F" "diff" >nul

只复制文件不创建目录。
我也尝试使用 powershell 但结果与 @copy 相同。

有人可以帮助我解决这个具体问题吗?

提前致谢!

因为这是用 powershell 标签标记的,这就是我在 powershell 中的做法。

首先用目录名设置一些变量:

#create path variables
$olddir = "C:\oldFolder"
$newdir = "C:\newFolder"
$diffdir = "C:\diffFolder"

现在,使用带有 -recurse 参数的 get-childitem 获取每个目录中的文件列表,通过 where-object 过滤目录:

#Get the list of files in oldFolder
$oldfiles = Get-ChildItem -Recurse -path $olddir | Where-Object {-not ($_.PSIsContainer)}

#get the list of files in new folder
$newfiles = Get-ChildItem -Recurse -path $newdir | Where-Object {-not ($_.PSIsContainer)}

现在,比较列表,但只比较 LastWriteTime 属性(可以使用 Length 代替或与 LastWriteTime - LastWriteTime,Length 并用)。

确保使用 -Passthru 选项,以便每个文件都作为对象传递,所有文件属性仍可访问。

管道通过 sort-object 以按 LastWriteTime 属性排序,因此文件从旧到新处理。然后进入 foreach 循环:

Compare-Object $oldfiles $newfiles -Property LastWriteTime -Passthru | sort LastWriteTime | foreach {

在循环中,为每个文件构建保留目录结构的新名称(用 diffdir 路径替换 olddir 和 newdir 路径)。

使用 Split-Path 获取新路径的目录并测试它是否存在 - 如果不存在,使用 mkdir 创建它,因为 copy-item 不会创建目标目录,除非复制目录,而不是文件。

然后,复制文件(您可以在复制命令中使用 -whatif 选项让它只告诉您它将复制什么,而不是实际执行):

     $fl = (($_.Fullname).ToString().Replace("$olddir","$diffdir")).Replace("$newdir","$diffdir")
     $dir = Split-Path $fl
     If (!(Test-Path $dir)){
        mkdir $dir
     }
     copy-item $_.Fullname $fl
}

所以完整的脚本是:

#create path variables
$olddir = "C:\oldFolder"
$newdir = "C:\newFolder"
$diffdir = "C:\diffFolder"

#Get the list of files in oldFolder
$oldfiles = Get-ChildItem -Recurse -path $olddir | Where-Object {-not ($_.PSIsContainer)}

#get the list of files in new folder
$newfiles = Get-ChildItem -Recurse -path $newdir | Where-Object {-not ($_.PSIsContainer)}

Compare-Object $oldfiles $newfiles -Property LastWriteTime -Passthru | sort LastWriteTime | foreach {
     $fl = (($_.Fullname).ToString().Replace("$olddir","$diffdir")).Replace("$newdir","$diffdir")
     $dir = Split-Path $fl
     If (!(Test-Path $dir)){
        mkdir $dir
     }
     copy-item $_.Fullname $fl
}