在两个相似但不匹配的目录树之间复制文件

问题描述

我有一个source目录结构和一个destination目录结构。 destination目录结构是source目录结构的子集。也就是说,在destination目录结构中,某些子文件夹不存在。

我想将*.jpg的某些文件source复制到destination,并且我不想在destination创建丢失的文件夹。我认为,由于这个原因,我不能使用robocopyxcopy,因为当使用/S /E开关时,它们将在目标位置重新创建源结构。

因此情况如下:

source
  folder1
    subfolder1
      file1.jpg
  folder2
    file2.jpg
  folder3
    file3.jpg
destination (before copying)
  folder1
    subfolder1
  folder3
destination (after copying)
  folder1
    subfolder1
      file1.jpg
  folder3
    file3.jpg

我尝试使用以下方法

@echo off
setlocal EnableDelayedExpansion
set src_dir=l:\DP\
set dest_dir=l:\test

for /R "%src_dir%" %%x in (*.jpg) do (
    copy "%%x" "%dest_dir%\%%x"
)

我非常确定问题出在"%dest_dir%\%%x",但不知道如何解决。我收到的错误消息的英文翻译是“文件,目录或驱动器的语法错误。”

谢谢您的帮助!

解决方法

不幸的是,没有xcopyrobocopy的开关阻止它创建目录。

无论如何,这是一个可以灵活完成任务的脚本(请参见rem备注):

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_SOURCE=%~dp0source"      & rem // (full path to source directory)
set "_TARGET=%~dp0destination" & rem // (full path to target directory)
set "_MASKS=*.jpg"             & rem // (`|`-separated list of patterns)
set "_MODE=A"                  & rem // (see below for possible modes)
set "_DIRS="                   & rem // (if empty,do not create sub-direcories)

rem // Resolve mode setting:
if /I "%_MODE%"=="A" (           rem // (`A`ll,copy new,overwrite existing)
    set "OPT=/-Y"
) else if /I "%_MODE%"=="R" (    rem // (`R`enew,overwrite older)
    set "OPT=/D"
) else if /I "%_MODE%"=="N" (    rem // (`N`ew,maintain existing)
    set "OPT= "
) else if /I "%_MODE%"=="P" (    rem // (re`P`lace,skip new,overwrite existing)
    set "OPT=/U"
) else if /I "%_MODE%"=="U" (    rem // (`U`pdate,overwrite older)
    set "OPT=/D /U"
) else exit /B 1

rem // Ensure that target directory exists:
mkdir "%_TARGET%" 2> nul & pushd "%_TARGET%" && (
    rem // Change into source directory:
    pushd "%_SOURCE%" && (
        rem // Resolve list of file name patterns and loop through them:
        setlocal EnableDelayedExpansion
        for /F "eol=| delims=" %%M in (^"!_MASKS:^|^=^
%= mandatory blank line,do not (re-)move! =%
!^"        ) do (
            if "!!"=="" endlocal
            rem // Loop through applicable file paths relative to source directory:
            for /F "tokens=1* delims=:" %%E in ('
                xcopy "%%~M" "%_TARGET%" /L /E /I %OPT:/U=% /Y
            ') do (
                set "FLAG=#" & if "%%F"=="" set "FLAG="
                rem // Check whether target sub-directory and file already exists:
                if not exist "%_TARGET%\%%F\.." (
                    if defined _DIRS (md "%_TARGET%\%%F\..") else set "FLAG="
                )
                if "%OPT%"==" " if exist "%_TARGET%\%%F" set "FLAG="
                if not "%OPT:/U=%"=="%OPT%" if not exist "%_TARGET%\%%F" set "FLAG="
                rem // Actually copy current file:
                if defined FLAG copy /Y "%%F" "%_TARGET%\%%F" > nul
            )
        )
        rem // Return from source directory:
        popd
    )
    rem // Return from target directory:
    popd
)

endlocal
exit /B