1

Windows 7 マシンで、同じサブフォルダーの一部 (すべてではない) と同じファイルの一部 (すべてではない) を持つ 2 つのディレクトリを結合しようとしています。コピーしたい

たとえば、次のディレクトリ構造があり、「Dir_A」と「Dir_Z」を結合 (コピーまたは移動) したいとします。ファイルが宛先ディレクトリに存在する場合、ファイルサイズを比較して、2 つのファイルのうち大きい方を維持したいと考えています。

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

これがエレガントではないことをお詫びします。

4

1 に答える 1

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 をクリアする 2 行をコメントアウトしましたが、現在のディレクトリのフォルダー 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"
于 2013-09-21T14:03:18.063 に答える