Home > front end >  Batch script - How to zip latest file in directory
Batch script - How to zip latest file in directory

Time:07-12

I'm making a handy dandy little batch file program (partly for fun) that helps me back up my game saves easily. The code I'm using is basically this:

"D:\7-Zip\7z.exe" a "destination path" "source path"

This has seemed to work great, but is only practical to save games where there is only a single save within a folder or maybe if the name of the save file never changes. This is because if there were several saves in the saves folder like:

Save 55
Save 54
Save 53

Then it would add all of them to the archive instead of just the latest one like I want. So my question is how can I only archive the latest file in these cases. Or the file with greatest number in the name.

CodePudding user response:

Sorting by "greatest number" does not work (5 is bigger than 20, due to strict string comparison), so I'l focus on "latest write access", which will also work when the game has several "save slots" and you might save with "slot 3` (not the highest number, but the latest gamesave)

dir has an option to sort files by time: /o-d sorts newest files first, /tw sets the sort criteria to "last write access" (see dir /? for more information). Use a for /f loop to capture the output (see for /?):

@echo off
set "latest="
for /f "delims=" %%a in ('dir /tw /o-d "save*"') do if not defined latest set "latest=%%a"
echo latest save game: %latest%

CodePudding user response:

There could be used the following batch file for this simple task if the batch file is in the directory with the Save files of the game.

@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "delims=" %%I in ('dir "%~dp0Save *" /A-D /B /O-D 2^>nul ^| %SystemRoot%\System32\findstr.exe /E /I /L /V ".zip"') do "D:\7-Zip\7z.exe" a -bd -bso0 -tzip -mx9 -y "destination path\%%~nI.zip" "%~dp0%%I" & goto EndBatch
echo Could not find any "Save *" file!
:EndBatch
endlocal

%~dp0 is expanded to full path of the batch file always ending with a backslash. If the batch file should use the current directory as source directory instead of the batch file directory, just remove all %~dp0. If the batch file should use a specific source directory, replace all %~dp0 by the source directory path ending with \.

destination path\ must be adapted to whatever is wanted as destination directory path which can be also %~dp0 to reference the directory containing the batch file.

There is executed in background one more cmd.exe with option /c to run its internal command DIR to search in the specified directory for files matching the wildcard pattern Save * and to output just the names of the found files without path in order from newest to oldest according to last modification time. This list of file names is redirected to FINDSTR which filters out case-insensitive all file names ending with the file extension .zip in case of the ZIP files are created also in the directory as the Save files.

The newest Save * file not having the file extension .zip is compressed with 7-Zip using the ZIP compression format with best compression without any output, except an error occurs like the file to compress cannot be read at the moment. Then the batch file processing continues below the label EndBatch which means the other file names output by DIR are ignored for further processing.

An information message is output if there could not be found any Save file in the specified directory by DIR.

The ZIP file is created with the name of the Save file compressed into the ZIP file.

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 /?
  • findstr /?
  • for /?
  • goto /?
  • setlocal /?

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

See single line with multiple commands using Windows batch file for an explanation of the unconditional command operator &.

  • Related