0

I want to Zip each day the files that were created on that same day (into one zipped folder) and erase the not zipped files of that day. I have this batch for zipping files that were created with the same name:

@echo off
for %%A in ("E:\Logs\SmartLogger\*") do (if /I not "%%~xA" == ".zip" 7za.exe a -tzip -mx5 -y -- "%%~dpnA.zip" "%%~A" >nul && del /Q /F "%%~A")

How can I change it to ignore the name but respect the date? For example, If I have files created on one day that are:

doc1.dat
doc2.dat
doc3.dat

Each day I'm creating those files and I want to zip them per day. I'm using 7zip btw

Satya
  • 8,693
  • 5
  • 34
  • 55
  • can you explain what you mean by "ignore the name but respect the date" ? – Nitesh Singh Mar 05 '17 at 09:13
  • Means that it doesn't matter which files were created that day, I just want to zip them all to one zipped folders and erase those that were created that day after zipping. – Sophie Kobzantsev Mar 05 '17 at 09:55
  • What files do you want to remove? It is not clear as question asks for non zipped files, but sample code removes zipped files. – MC ND Mar 05 '17 at 10:45
  • Is it also possible to use WinRAR? I'm asking that because of using WinRAR (shareware) nothing else than WinRAR is needed for this task, no FOR, no time comparisons in command line, etc. just `WinRAR.exe`. – Mofi Mar 05 '17 at 10:50
  • Yeah winrar is good as well but I need a batch to run it automatically through a task scheduler everyday – Sophie Kobzantsev Mar 05 '17 at 11:16

3 Answers3

1

My first suggestion is using WinRAR.

This command line can be used as scheduled task command line directly as also in a batch file.

"%ProgramFiles%\WinRAR\WinRAR.exe" m -afzip -agYYY-MM-DD -cfg- -ep1 -ibck -inul -m5 -tn1d -x*.zip -y -- "E:\Logs\SmartLogger\Logs_.zip" "E:\Logs\SmartLogger\*"

The help of WinRAR opened by clicking in GUI main window of WinRAR in menu Help on menu item Help topics contains on tab Contents the list item Command line mode with the help pages:

  • Command line syntax
  • Commands
    • Alphabetic commands list
  • Switches
    • Alphabetic switches list

A command line as above can be easily written on using those 3 help pages and reading the help pages of the switches which seem to be interesting for the current compression/extraction task.

See the Alphabetic switches list to understand the used switches and how this single line makes the entire job.


My second suggestion is using 7-Zip which really requires a batch file as 7-Zip (of version 16.04) does not have switches for file date depending (backup/compression) operations.

Here is my solution using 7-Zip compressing each file with last modification date being todays date into a *.zip file with Logs_YYYY-MM-DD.zip as file name.

@echo off
setlocal EnableExtensions EnableDelayedExpansion

set "ListFile=%TEMP%\ListFile.tmp"
del "%ListFile%" 2>nul

rem Get todays date in region and language dependent format required for
rem last modification date evaluation of all files in source directory.

echo Get todays file date.>"%TEMP%\GetTodaysFileDate.tmp"
for %%I in ("%TEMP%\GetTodaysFileDate.tmp") do set "Today=%%~tI"
set "Today=%Today:~0,-6%"
del "%TEMP%\GetTodaysFileDate.tmp"
echo Today is: "%Today%"

rem Set current directory being the directory with the files to process.
cd /D "E:\Logs\SmartLogger"

rem Search with DIR for files with todays date as last modification date
rem output by DIR sorted by last modification date with newest file first.
rem The found files with todays date are written into a list file. The
rem loop is exited if the first file is processed not having todays date.

for /F "delims=" %%I in ('dir /A-D /B /O-D /TW * 2^>nul') do (
    set "FileDate=%%~tI"
    set "FileDate=!FileDate:~0,-6!"
    if not "!FileDate!" == "%Today%" goto CompressFiles
    if /I not "%%~xI" == ".zip" echo %%I>>"%ListFile%"
)

:CompressFiles
if not exist "%ListFile%" goto EndBatch

rem Get todays date in a Windows region and language settings
rem independent format for usage in the ZIP file name.

for /F "skip=1 delims=." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime') do set "CurrentDate=%%I" & goto ReformatDate
:ReformatDate
set "ZipFileName=Logs_%CurrentDate:~0,4%-%CurrentDate:~4,2%-%CurrentDate:~6,2%.zip"

"%ProgramFiles(x86)\7-Zip\7z.exe" a -tzip -mx5 -scsDOS -sdel -y -- %ZipFileName% "@%ListFile%" >nul

del "%ListFile%"

rem Restore the environment (environment variables, current directory,
rem state of command extensions and delayed expansion) before calling
rem the command SETLOCAL at top of this batch file.

:EndBatch
endlocal

This batch file expects that the folder does not contain any file with a last modification date in future in comparison to todays date. This limitation is caused by the optimized evaluation of the file dates of all files found in the directory with the log files. This limitation does not exist on removing the line with goto CompressFiles in the FOR loop.

Also 7-Zip has a help file which is 7zip.chm in program files folder of 7-Zip which after opening with a double click contains on tab Contents under list item Command Line Version the help pages

  • Syntax
  • Commands opening Command Line Commands
  • Switches opening Command Line Switches

Please first check if the line echo Today is: "%Today%" really outputs on the machine running this batch file under the user account defined for the scheduled task just the file date (without or with weekday) not including a space character and file time.

The Windows region and language settings of used user account determine the date/time format of %%~tI. The SET command lines below the two command lines with %%~tI must be perhaps adapted to get just todays date without time.

It would be possible to use WMIC also for getting the last modification date of each file as described in answer on Find out if file is older than 4 hours in batch file, but that is really slow and would require even more code.

For understanding the used Windows 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.

  • cd /?
  • del /?
  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • rem /?
  • set /?
  • setlocal /?

Read also the Microsoft article about Using Command Redirection Operators for an explanation of >nul and 2>nul.

Community
  • 1
  • 1
Mofi
  • 46,139
  • 17
  • 80
  • 143
0
@echo off
    setlocal enableextensions disabledelayedexpansion

    rem Try to change to target folder. Leave on error
    pushd "E:\Logs\SmartLogger" || goto :eof

    rem Retrieve the today date to use as zip file name
    set "today=" & for /f "tokens=1-3 delims=/ " %%a in ('
        robocopy "|" . /njh
    ') do if not defined today set "today=%%a-%%b-%%c"

    rem We need a temporary file to store the list of files to process
    set "listFile=%temp%\%~nx0.%random%%random%%random%%random%.tmp"

    rem Retrieve the list of files generated today and save to temp file
    >"%listFile%" forfiles /D 0 /M *.dat

    rem On sucess (files found) compress the list of selected files
    if not errorlevel 1 (
        7za -tzip -mx5 -y -- "%today%.zip" @"%listfile%"
    )

    rem On sucess remove the zipped files 
    if not errorlevel 1 (
        >nul 2>nul (
            for /f "usebackq delims=" %%a in ("%listFile%") do del /q /f "%%~fa"
        )
    )

    rem Remove the temporary file 
    2>nul del /q /f "%listFile%"
MC ND
  • 69,615
  • 8
  • 84
  • 126
-1

I tried using MC ND's solution, but it does not work when I use the @ operator, the file with the list was not being found. It works if there is a single file.

The -- parameter right before the destination and source parameters was causing the issue when using the @listfile mode.

Hope that helps anyone that encounters the same issue

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140