1

How to copy the latest / newest file within a folder first?

For example my code copies the latest folder to the remote machine first which is exactly what I want to do.

But how do I transfer the latest file first within the given folder?

setlocal
set "sourceDir=C:\AutoFrameworkResults"
set "destDir=\xxx.1xx.1.xx\c$\Common\AutoFrameworkResults"

for /f "delims=" %%d in ('dir "%sourceDir%" /o-d /ad /b') do (
    xcopy /y /s "%sourceDir%\%%d" "%destDir%\%%d\"
)

Example output (in the wrong order, should be reversed):

C:\AutoFrameworkResults\15 May 2017\01.20.50\Time.01.20.57, Test1.jpeg
C:\AutoFrameworkResults\15 May 2017\01.20.50\Time.01.20.59, Test2.jpeg
C:\AutoFrameworkResults\15 May 2017\01.20.50\Time.01.21.14, Test3.jpeg
C:\AutoFrameworkResults\15 May 2017\01.20.50\Time.01.21.20, Test4.jpeg
2
  • Try adding ^| SORT /R to the quoted dir command in your for loop. (You might find SS64's CMD reference a convenient site to have on a bookmark) Commented May 15, 2017 at 12:57
  • just in reverse order? What is sorting your files? It's dir parameter /o-d. What about using /od instead?
    – Stephan
    Commented May 15, 2017 at 16:11

1 Answer 1

1

First, a UNC path as used for destination directory must start with two backslashes \\ and not just one backslash \.

Second, DIR command option /ad means list any entry in specified directory with directory attribute set which is the reason why only subdirectories are output by DIR and further processed by FOR.

So what is needed to copy only the newest file in a specified directory is something like this:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceDir=C:\AutoFrameworkResults\15 May 2017\01.20.50"
set "DestDir=\\xxx.1xx.1.xx\c$\Common\AutoFrameworkResults"

for /F "eol=| delims=" %%I in ('dir "%SourceDir%\*" /A-D /B /O-D 2^>nul') do (
    %SystemRoot%\System32\xcopy.exe "%SourceDir%\%%I" "%DestDir%\" /C /H /I /K /Q /R /Y >nul
    goto NewestFileCopied
)

:NewestFileCopied
endlocal

The command DIR outputs any directory entry not having directory attribute set because of /A-D which means any file. The output should be in bare format because of /B which means here only the file name with file extension. And the output should be according to last modification date in reverse order because of /O-D (date in reverse order) and implicit /TW (write time) which is the default and therefore must not be explicitly specified.

The error message output by DIR in case of no file found in specified directory is suppressed by redirecting handle STDOUT to device NUL using 2>nul. It is necessary here to escape the redirection operator > with caret character ^ to be interpreted as literal character by Windows command interpreter on parsing the FOR command line, but as redirection operator later when FOR executes the DIR command line in a separate command process in background.

The loop is exited with GOTO command after having copied the newest file.

But it looks like the requirement for this file copying task is that the batch code needs to find out also what is the newest subdirectory in 2 directory levels. In this case it is necessary to use 2 more FOR loops.

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceDir=C:\AutoFrameworkResults"
set "DestDir=\\xxx.1xx.1.xx\c$\Common\AutoFrameworkResults"

for /F "eol=| delims=" %%A in ('dir "%SourceDir%\*" /AD /B /O-D 2^>nul') do (
    for /F "eol=| delims=" %%B in ('dir "%SourceDir%\%%A\*" /AD /B /O-D 2^>nul') do (
        for /F "eol=| delims=" %%C in ('dir "%SourceDir%\%%A\%%B\*" /A-D /B /O-D 2^>nul') do (
            %SystemRoot%\System32\xcopy.exe "%SourceDir%\%%A\%%B\%%C" "%DestDir%\%%A\%%B\" /C /H /I /K /Q /R /Y >nul
            goto NewestFileCopied
        )
    )
)

:NewestFileCopied
endlocal

An even more complex code would be necessary in case of number of directory levels is also unknown by using a subroutine for determining the newest directory in current directory which calls itself for each directory found which means a recursively called subroutine is used in batch file.

The batch code below copies all files in newest directory in order of latest to oldest file:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceDir=C:\AutoFrameworkResults"
set "DestDir=\\xxx.1xx.1.xx\c$\Common\AutoFrameworkResults"

for /F "eol=| delims=" %%A in ('dir "%SourceDir%\*" /AD /B /O-D 2^>nul') do (
    for /F "eol=| delims=" %%B in ('dir "%SourceDir%\%%A\*" /AD /B /O-D 2^>nul') do (
        for /F "eol=| delims=" %%C in ('dir "%SourceDir%\%%A\%%B\*" /A-D /B /O-D 2^>nul') do (
            %SystemRoot%\System32\xcopy.exe "%SourceDir%\%%A\%%B\%%C" "%DestDir%\%%A\%%B\" /C /H /I /K /Q /R /Y >nul
        )
        goto NewestFilesCopied
    )
)

:NewestFilesCopied
endlocal

But honestly I really don't understand the requirement to copy the files from latest to oldest on copying all files from newest directory. It would be faster for copying all files in newest directory to use this code:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceDir=C:\AutoFrameworkResults"
set "DestDir=\\xxx.1xx.1.xx\c$\Common\AutoFrameworkResults"

for /F "eol=| delims=" %%A in ('dir "%SourceDir%\*" /AD /B /O-D 2^>nul') do (
    for /F "eol=| delims=" %%B in ('dir "%SourceDir%\%%A\*" /AD /B /O-D 2^>nul') do (
        %SystemRoot%\System32\xcopy.exe "%SourceDir%\%%A\%%B\*" "%DestDir%\%%A\%%B\" /C /H /I /K /Q /R /Y >nul
        goto NewestFilesCopied
    )
)

:NewestFilesCopied
endlocal

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • set /?
  • setlocal /?
  • xcopy /?

Read also the Microsoft article about Using command redirection operators.

0

Not the answer you're looking for? Browse other questions tagged or ask your own question.