batch-filecommand-prompt

Copy the newest versions of multiple files


I am looking for a Batch Script to look after the most recent versions of a file.

The file name is automatically generated and often these files are having multiple versions. I am looking for a way to get the most recent ones.

The file name follows the same pattern: [ID]_[Week]_[Version]_[Othertext]

example:

Here, 12345 is [ID], 2440 is [Week], 01 is [Version], 2_11 is [Other text]. The most recent one is the one with highest version. In that case 03. Other text isn't relevant, so you can ignore it. The grouping is based on ID, week and version.

Today, I am using a very simple script as I have no idea how many version each file is having - 1 or 20 and then manually deleting the old ones.

copy \\server\folder\subfolder\12345_2440* C:\folder\
copy \\server\folder\subfolder\34567_2440* C:\folder\
set /p=

I am looking a smarter way to copy only what I need. In the case above, I want to copy 12345_2440_03_2_11.csv and 34567_2440_05_2_11.csv, not all 8 files.

Is there any easy script to do that?


Solution

  • All three solutions provided below require that the number of version digits is identical for all files with same identifier and week. In the example file names list all files have version numbers with two digits.

    There can be used the following batch file if neither source folder path nor destination folder path nor any file name contains one or more !.

    @echo off
    setlocal EnableExtensions EnableDelayedExpansion
    set "SourceFolder=\\server\folder\subfolder"
    set "DestinationFolder=C:\folder"
    md "!DestinationFolder!" 2>nul
    if not exist "!DestinationFolder!\" echo ERROR: Missing folder: "!DestinationFolder!"& exit /B 1
    set "ID_Week="
    for /F "delims=" %%G in ('dir "!SourceFolder!\*_*_*_*.csv" /A-D /B /O-N 2^>nul') do for /F "tokens=1,2 delims=_" %%I in ("%%G") do if not "!ID_Week!" == "%%I_%%J" set "ID_Week=%%I_%%J" & copy "!SourceFolder!\%%G" "!DestinationFolder!\" 1>nul
    endlocal
    

    There can be used the following batch file if source or destination folder path contains one or more ! but no file name is with an exclamation mark.

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    set "SourceFolder=\\server\folder\subfolder"
    set "DestinationFolder=C:\folder"
    md "%DestinationFolder%" 2>nul
    if not exist "%DestinationFolder%\" echo ERROR: Missing folder: "%DestinationFolder%"& exit /B 1
    setlocal EnableDelayedExpansion
    set "ID_Week="
    for /F "delims=" %%G in ('dir "!SourceFolder!\*_*_*_*.csv" /A-D /B /O-N 2^>nul') do for /F "tokens=1,2 delims=_" %%I in ("%%G") do if not "!ID_Week!" == "%%I_%%J" set "ID_Week=%%I_%%J" & copy "!SourceFolder!\%%G" "!DestinationFolder!\" 1>nul
    endlocal
    endlocal
    

    The following batch file is the slowest but works even with a file name containing one or more exclamation marks in other text part.

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    set "SourceFolder=\\server\folder\subfolder"
    set "DestinationFolder=C:\folder"
    md "%DestinationFolder%" 2>nul
    if not exist "%DestinationFolder%\" echo ERROR: Missing folder: "%DestinationFolder%"& exit /B 1
    set "ID_Week="
    for /F "delims=" %%G in ('dir "%SourceFolder%\*_*_*_*.csv" /A-D /B /O-N 2^>nul') do for /F "tokens=1,2 delims=_" %%I in ("%%G") do (
        setlocal EnableDelayedExpansion
        if not "!ID_Week!" == "%%I_%%J" (
            endlocal
            set "ID_Week=%%I_%%J"
            copy "%SourceFolder%\%%G" "%DestinationFolder%\" 1>nul
        ) else endlocal
    )
    endlocal
    

    The main trick is getting a list of matching CSV file names in source folder ordered reverse by name and copy always the first file in the list if the identifier and week part changes in comparison to identifier and week stored currently in environment variable ID_Week.

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

    Read the Microsoft documentation about Using command redirection operators for an explanation of 1>nul and 2>nul. The redirection operator > must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir command line with using a separate command process started in background with %ComSpec% /c and the command line within ' appended.

    Single line with multiple commands using Windows batch file explains the unconditional command operator & as used in all code examples. There is no space left to & after command echo as otherwise the command echo would output this space as trailing space too.