我试图在Windows 7计算机上组合两个目录,这些目录具有一些相同的子文件夹(但不是全部)和一些相同的文件(但不是全部)。我想复制
例如,我有以下目录结构,想要组合(复制或移动)" Dir_A"和" Dir_Z"。如果文件存在于目标目录中,我想比较文件大小并保留两个文件中较大的文件。
Dir A
Dir B
file 1.txt
file 2.txt
file 3.txt
Dir C
file 4.txt
Dir D
file 5.txt
file 6.txt
Dir_Z
Dir Y
file 8.txt
Dir C
file 4.txt
Dir D
file 6.txt
我很舒服使用cmd文件或PowerShell。先感谢您。
编辑:修改以在导演和文件名中包含空格并添加到目前为止的内容。
这是我到目前为止所做的事情。它似乎适用于目录或文件名中有空格的情况。
@echo off
echo :: Combine two folders, Keep the larger of any given files, Delete the other
if "%1"=="" goto :NoParam
if "%2"=="" goto :NoParam
setlocal enabledelayedexpansion
set SOURCE_DIR=%1
set DEST_DIR=%2
for /R "%SOURCE_DIR%" %%S in (*) do (
echo Source: "%%S"
@echo off
for /f "delims=" %%R in ('call MakeRelative.cmd "%%S" "%SOURCE_DIR%"') do (
set FILE_REL="%%R"
set filename=%DEST_DIR%\%%R
For %%D in ("!filename!") do (
Set Name=%%~nxD
if exist %DEST_DIR%\%%R (
echo File Exists
if %%~zD lss %%~zS (
echo Destination %%~zD is smaller than Source %%~zS
call robocopy %%~dpS %%~dpD "!Name!" /MOV
) else del %%S && Echo File is not larger, Deleting %%S
) else call robocopy %%~dpS %%~dpD "!Name!" /MOV
)
)
)
Pause
goto :eof
:NoParam
echo.
echo Syntax: %0 [Source_DIR] [Dest_DIR]
goto :eof
我使用了MakeRelative.cmd,如下所示:http://www.dostips.com/DtCodeCmdLib.php#MakeRelative
我很抱歉这不优雅。
答案 0 :(得分:0)
我不是一个PowerShell开发人员,但是这应该做的工作,并且希望它比批处理文件更明显。
if($args.length -ne 3) {
"usage: PowerShell ThisScriptName.ps1 -command ""SourceDirectory"" ""DestinationDirectory""";
Exit
}
function CopyFileIfSourceIsLarger($SourceFile, $DestinationFile) {
$S = New-Object IO.FileInfo($SourceFile.ToString());
$D = New-Object IO.FileInfo($DestinationFile.ToString());
if ($S.Length -gt $D.Length ) {
"Overwriting smaller file " + $D.FullName;
[IO.File]::Copy($S.FullName, $D.FullName, $true);
}
}
$SourceDir = New-Object IO.DirectoryInfo($args[1]);
$DestinationDir = New-Object IO.DirectoryInfo($args[2]);
$SourceDirectoryPath = $SourceDir.FullName;
$DestinationDirectoryPath = $DestinationDir.FullName;
"Source Path: " + $SourceDirectoryPath;
"Destination Path: " + $DestinationDirectoryPath;
$SourceItems = Get-ChildItem -recurse $SourceDir;
"Synchronizing Directory Structure..."
foreach ($dir in $SourceItems | ? { $_ -is [IO.DirectoryInfo] }) {
$sourceRelative = $dir.fullname.Substring($SourceDirectoryPath.length + 1);
if ([IO.Directory]::Exists([IO.Path]::Combine($DestinationDirectoryPath,$sourceRelative)) -eq $false) {
"Creating folder " + [IO.Path]::Combine($DestinationDirectoryPath,$sourceRelative);
[IO.Directory]::CreateDirectory([IO.Path]::Combine($DestinationDirectoryPath,$sourceRelative)) | out-null;
}
}
"Synchronizing Files..."
foreach ($file in $SourceItems | ? { $_ -is [IO.FileInfo] }) {
$sourceRelative = $file.fullname.Substring($SourceDirectoryPath.length + 1);
if ([IO.File]::Exists([IO.Path]::Combine($DestinationDirectoryPath,$sourceRelative)) -eq $true) {
CopyFileIfSourceIsLarger ([IO.Path]::Combine($SourceDirectoryPath,$sourceRelative).ToString()) ([IO.Path]::Combine($DestinationDirectoryPath,$sourceRelative).ToString());
} else {
"Creating file " + [IO.Path]::Combine($DestinationDirectoryPath,$sourceRelative);
[IO.File]::Copy([IO.Path]::Combine($SourceDirectoryPath,$sourceRelative).ToString(),[IO.Path]::Combine($DestinationDirectoryPath,$sourceRelative).ToString()) | out-null;
}
}
"All done."
#Thanks to:
#"Identifying Object Types": http://powershell.com/cs/blogs/tobias/archive/2008/10/14/identifying-object-types.aspx
#"Exiting early from foreach": http://stackoverflow.com/questions/10277994/powershell-how-to-exit-from-foreach-object
#"Calling functions with multiple parameters" http://stackoverflow.com/questions/4988226/powershell-multiple-function-parameters
当脚本运行时,文件1,2,3,5,9和10会被复制,文件6会被覆盖,因为它在目标中较小。
这是一个批处理文件,用于设置测试用例(以及一些额外的文件夹来测试名称中的空格)。为了安全起见,我已经注释掉清除目录A和Z的两行,但是如果你不关心删除当前目录中文件夹A和Z中的文件,你可以删除REM语句。
@ECHO OFF
REM Uncomment at own risk RD /S /Q A
REM Uncomment at own risk RD /S /Q Z
MD "A\B"
echo aaaaaaaabbbbbbbbcccccccc>"A\B\file 1.txt"
echo aaaaaaaabbbbbbbbcccccccc>"A\B\file 2.txt"
echo aaaaaaaabbbbbbbbcccccccc>"A\B\file 3.txt"
MD "A\C"
echo aaaaaaaabbbbbbbbcccccccc>"A\C\file 4.txt"
MD "A\D"
echo aaaaaaaabbbbbbbbcccccccc>"A\D\file 5.txt"
echo aaaaaaaabbbbbbbbcccccccc>"A\D\file 6.txt"
MD "A\FOLDER E"
echo aaaaaaaabbbbbbbbcccccccc>"A\FOLDER E\file 9.txt"
echo aaaaaaaabbbbbbbbcccccccc>"A\FOLDER E\file 10.txt"
MD "Z\Y"
echo aaaaaaaabbbbbbbbcccccccc>"Z\Y\file 8.txt"
MD "Z\C"
echo aaaaaaaabbbbbbbbccccccccdddddddd>"Z\C\file 4.txt"
MD "Z\D"
echo aaaaaaaa>"Z\D\file 6.txt"