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.
34567_2440_01_2_11.csv
34567_2440_02_2_11.csv
34567_2440_03_2_11.csv
34567_2440_04_2_11.csv
34567_2440_05_2_11.csv
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?
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.
copy /?
dir /?
echo /?
endlocal /?
exit /?
for /?
if /?
md /?
set /?
setlocal /?
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.