问题
I was trying to compare files in 2 folders and copy those new and updated files to a diff folder, for example:
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
In this case, what I expect in diff folder should be:
diffFolder
a\aa.txt
b\ab.exe
b\ac.config
aa.txt
ab.exe
So far I have been searching on google and trying different approaches, but still cannot achieve this.
I have get the files list includes files needed to be copied along with their path by usingxcopy /edyl "newFolder\*" "oldFolder"
and was trying using
for /f %%F in ('xcopy /e /dyl "new\*" "old"') do @xcopy %%F diff /e
this messes up diffFolder
also tried
for /f %%F in ('xcopy /e /dyl "new\*" "old"') do @robocopy new diff %%F /e
this only create directories in diffFolder but not copy files, gave me error: invalid parameter #3 :"newFolder\a\aa.txt"
for /f %%F in ('xcopy /e /dyl "new\*" "old"') do @copy "%%F" "diff" >nul
only copy files not create directories.
I was also trying to use powershell but result the same with @copy.
Any one can help me on this specific issue?
Thanks in advance!
回答1:
Since this is tagged with a powershell
tag, this is how I would do it in powershell.
First setup some variables with directory names:
#create path variables
$olddir = "C:\oldFolder"
$newdir = "C:\newFolder"
$diffdir = "C:\diffFolder"
Now, get the list of files in each directory using get-childitem
with -recurse
parameter, piped through where-object
to filter out directories:
#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)}
Now, compare the lists, but compare only the LastWriteTime
property (can use Length
instead of or alongside LastWriteTime
- LastWriteTime,Length
).
Make sure to use the -Passthru
option so that each file is passed through as an object with all file properties still accessible.
Pipe through sort-object
to sort on LastWriteTime
attribute, so files are processed oldest to newest. Then pipe into a foreach
loop:
Compare-Object $oldfiles $newfiles -Property LastWriteTime -Passthru | sort LastWriteTime | foreach {
In the loop, for each file, build the new name retaining the directory structure (replace olddir and newdir paths with diffdir path).
Get just the directory of the new path using Split-Path
and test if it exists - if it doesn't, create it using mkdir
as copy-item
won't create target directory unless copying a directory, not a file.
Then, copy the file (you can use the -whatif
option in the copy command to have it just tell you what it would copy, without actually doing it):
$fl = (($_.Fullname).ToString().Replace("$olddir","$diffdir")).Replace("$newdir","$diffdir")
$dir = Split-Path $fl
If (!(Test-Path $dir)){
mkdir $dir
}
copy-item $_.Fullname $fl
}
So the full script is:
#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
}
来源:https://stackoverflow.com/questions/29994244/how-to-copy-updated-files-to-new-folder-and-create-directory-as-source-if-not-ex