Link to home
Start Free TrialLog in
Avatar of Sal Sorice
Sal SoriceFlag for United States of America

asked on

Batch file command to rename file to current date MINUS 7 days?

I have a backup batch file that runs weekly on a client server. Each week I want to rename the prior week backup with a date stamp before creating a new backup. This command works fine:

for /f "tokens=1-5 delims=/ " %%d in ("%date%") do rename "F:\Backups\Images\DriveD_FullBackup.sna" DriveD_FullBackup_%%e-%%f-%%g.sna

However...

To have the date stamp actually match the date the backup was taken (which was 7 days prior to the rename date), what I actually want to do is to rename the file with
[today's date - 7 days], so, for example, a backup made on January 1 would be renamed on January 8, BUT the rename command would have to subtract 7 days from the current date.

Any idea on how to modify the above command to do this?
Avatar of sg08234
sg08234
Flag of Germany image

Maybe     http://www.dostips.com/DtTipsDateTime.php     can help

Good luck - Michael
Avatar of Sal Sorice

ASKER

sg08234,

Thanks - interesting site. However, I'm not a programmer, so it's a bit over my head :^(

I'm hoping someone could give me the correct syntax to add to my original command.
OK - I'll try tomorrow - Michael
Can't you specify a file name in the application that actually creates the backup image as it is created?  That would be by far the most logical thing to do.

It would probably be better to actually get the file creation date or last modified date (whichever most accurately reflects the date of "last weeks" file) from the file itself rather that doing the maths.

I haven't used the Code Snippet box for the code below because it's currently screwed up and double-spaces all the lines.

Copy the following, paste into Notepad, and save as "GetFileDate.vbs" to a suitable drive and folder where you would choose to run your script from.


Set objFS=CreateObject("Scripting.FileSystemObject")
Set objArgs = WScript.Arguments
strFile= objArgs(0)
WScript.Echo objFS.GetFile(strFile).DateCreated
WScript.Echo objFS.GetFile(strFile).DateLastModified
WScript.Echo objFS.GetFile(strFile).DateLastAccessed


Copy the following, paste into Notepad, and save as "GetDate.cmd" in the same folder as the *.VBS file above.

@echo off
set TargetFile=F:\Backups\Images\DriveD_FullBackup.sna
set CurrDir=%~dp0
set CurrDir=%CurrDir:~0,-1%

if exist "%TargetFile%" (
    cscript //NoLogo "%CurrDir%\GetFileDate.vbs" "%TargetFile%"
) else (
    echo The file:
    echo "%TargetFile%"
    echo has not been found.  Check the path is correct.
)
pause


Double-Click on the *.CMD file.

Which of the 3 lines of output represents the date you wish to use for your file name?
In what format is the Date displayed on your system? (mm/dd/yyyy or dd/mm/yyyy)

We should be able to create a nice neat script that breaks up the elements of the file date stamp into a logical order (suggested yyyy-mm-dd) and use that to rename the backup file.
Avatar of Bill Prew
Bill Prew

It sounds like what you do right now is to do a backup and create a backup file without a date stamp in it.  Then a week from now you need to do that again, so want to rename the existing unstamped file with the date it was created.

My first thought / suggestion would be to rather just create each backup file with the current date in the name.  Then next week, no need for any renaming.  If your backup tool won't allow this for some reason, then you could follow the actual backup with a REName command in the batch script that does the backup, and rename to the current date (as you showed above) before ending the BAT script.

If that isn't useful for some reason, then I'd suggest the following adjustment to what you asked for.  Rather than calculate the date that you think the last backup was created, why not get the date from the file itself.  The Windows created, modified and acceessed dates are readily available and would be a more dependable indicator of when the file was created and therefore the date to add to its name.

et me know if either of these work for you and I'll help with some code.

~bp
Clearly, the Bills are on the same page on this one ;-).

~bp
What do you see when you enter the following command in DOS:

    echo %date%
The follwoing script will do the job of substracting 7 days. It might happen that you have to interchange year, monthe, date accoring to you local date format.


@rem: Source: http://www.robvanderwoude.com/datetiment.php#DateAdd

@ECHO ON
ECHO.

SETLOCAL

:: Convert "today" to Julian
@For /F "tokens=2,3,4 delims=/ " %%A in ('Date /t') do @(
      Set GMonth=%%A
      Set GDay=%%B
      Set GYear=%%C
)

CALL :JDate %GYear% %GMonth% %GDay%

:: Display original input
ECHO Starting date   : %cDate%

:: Subtract 7 days
SET /A NewJDate = %JDate% - 7

:: Convert the new Julian date back to Gregorian again
CALL :GDate %NewJDate%

:: Display the result
ECHO Resulting date  :
ECHO %GYear%
ECHO %GMonth%
ECHO %GDay%

ENDLOCAL

rename "F:\Backups\Images\DriveD_FullBackup.sna" DriveD_FullBackup_%GYear%-%GMonth%-%GDay%.sna


GOTO:EOF


::===================================::
::                                   ::
::   -   S u b r o u t i n e s   -   ::
::                                   ::
::===================================::


:GDate
:: Convert Julian date back to "normal" Gregorian date
:: Argument : Julian date
:: Returns  : YYYY MM DD
::
:: Algorithm based on Fliegel-Van Flandern
:: algorithm from the Astronomical Almanac,
:: provided by Doctor Fenton on the Math Forum
:: (http://mathforum.org/library/drmath/view/51907.html),
:: and converted to batch code by Ron Bakowski.
::
SET /A P      = %1 + 68569
SET /A Q      = 4 * %P% / 146097
SET /A R      = %P% - ( 146097 * %Q% +3 ) / 4
SET /A S      = 4000 * ( %R% + 1 ) / 1461001
SET /A T      = %R% - 1461 * %S% / 4 + 31
SET /A U      = 80 * %T% / 2447
SET /A V      = %U% / 11
SET /A GYear  = 100 * ( %Q% - 49 ) + %S% + %V%
SET /A GMonth = %U% + 2 - 12 * %V%
SET /A GDay   = %T% - 2447 * %U% / 80
:: Clean up the mess
FOR %%A IN (P Q R S T U V) DO SET %%A=
:: Add leading zeroes
IF 1%GMonth% LSS 20 SET GMonth=0%GMonth%
IF 1%GDay%   LSS 20 SET GDay=0%GDay%
:: Return value
SET GDate=%GYear% %GMonth% %GDay%
GOTO:EOF


:JDate
:: Convert date to Julian
:: Arguments : YYYY MM DD
:: Returns   : Julian date
::
:: First strip leading zeroes
SET MM=%2
SET DD=%3
IF %MM:~0,1% EQU 0 SET MM=%MM:~1%
IF %DD:~0,1% EQU 0 SET DD=%DD:~1%
::
:: Algorithm based on Fliegel-Van Flandern
:: algorithm from the Astronomical Almanac,
:: provided by Doctor Fenton on the Math Forum
:: (http://mathforum.org/library/drmath/view/51907.html),
:: and converted to batch code by Ron Bakowski.
SET /A Month1 = ( %MM% - 14 ) / 12
SET /A Year1  = %1 + 4800
SET /A JDate  = 1461 * ( %Year1% + %Month1% ) / 4 + 367 * ( %MM% - 2 -12 * %Month1% ) / 12 - ( 3 * ( ( %Year1% + %Month1% + 100 ) / 100 ) ) / 4 + %DD% - 32075
FOR %%A IN (Month1 Year1) DO SET %%A=
GOTO:EOF
scion111

I was thinking more along these lines however, I did ask you for the output of your ECHO %DATE% command....

NOTE: Ignore the XCOPY in line 25. It does absolutely nothing except validate dates.
@echo off
  rem Somehow, you need to get your date into d, m and y. Example:
  set /a d=%date:~0,2%
  set /a m=%date:~3,2%
  set /a y=%date:~6,4%

  echo %d%/%m%/%y%
  call :previousday 7
  echo %d%/%m%/%y%
exit /b

rem ---------------------------------------------------------------------
rem PREVIOUS DAY
rem ---------------------------------------------------------------------
:previousday
  if "%1"=="" goto :eof
  if %1 lss 1 goto :eof

  for /l %%a in (1,1,%1) do (
    :loop
      set /a d-=1 & if %d% lss 1 (
        set d=31 & set /a m-=1
        if %m% lss 1 set m=12 & set /a y-=1
      )
    xcopy /d:%m%-%d%-%y% /h /l "%~f0" "%~f0\" >nul 2>&1 || goto loop
  )
goto :eof

Open in new window

(Source: https://www.experts-exchange.com/OS/Microsoft_Operating_Systems/MS_DOS/A_4196-Advanced-Batch-File-Programming-TOMORROW-BAT.html)
Hi ~BP
Yes, on the same wave length and planet.  Date the file at the time rather than perform all the jiggery-pokery later on, or if that cannot be done get the date from the file itself - which in itself is a simple enough task.

scion111
There is probably already a nice little *.exe out there written for this very purpose.  How amenable are you to using little 3rd-party command line utility programs along with scripted solutions?
I just had a creazy idea.

What if you rename your back file with it's actually modified date?

Something like:
FOR /R "F:\Backups\Images" %%A in (DriveD_FullBackup.sna) do rename "%%fA" "%%~nA_%%~tA%%~xA"

Open in new window


May need some tweaking

Cheers,
Rene
Here is my fixed version

Hoping that helps!

Cheers,
Rene

@ECHO OFF
SETLOCAL EnableDelayedExpansion
FOR /R "F:\Backups\Images" %%A in (DriveD_FullBackup.sna) DO (
   REM FOR Date format:yyyy-mm-dd
   SET dd=%%~tA
   SET dd=!dd:~0,10!
   ECHO NEW FILE NAME:"%%~nA_!dd!%%~xA"
   rename"%%~fA" "%%~nA_!dd!%%~xA"
)

PAUSE
EXIT

Open in new window

Thanks all for the input!!!!

I will look over everything tomorrow and advise.

Just to clear up one point (that I should have mentioned originally). As BillD said:

"Can't you specify a file name in the application that actually creates the backup image as it is created?  That would be by far the most logical thing to do."

Yes, I could. But the backup utility (Drive Snapshot) creates a hash file which is needed for differential backups (which I'm using) and if I auto-name the backup file with the creation date the differential routine that runs on subsequent days won't be able to find the full backup file (ie, for example, it will be looking for a file called "FullBackup" and not "FullBackup_"2_13_2012"). Hope I've explained that clearly...

Again, thanks for all the input - will look over all comments, experiment tomorrow and let you know what I find.
Thanks for the clarification about the backup application's naming convention.  It was worth asking anyway, just in case.  You never know.  We have all been guilty of bypassing the obvious from time to time.
@Fellow Experts

If scion111 finds my approach to be good, feel free to optimize it. I prefer learning than points...

Cheers,
Rene
SOLUTION
Avatar of Bill Prew
Bill Prew

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Sorry for the delay everyone - down server yesterday :-(

Will test today and advise. Thanks again for all the help!
Rene,
Brilliant idea! Worked like a charm. And Bill, thanks for the tweaking (not that I understand the magic you both worked).

All others - thanks for theinput as well. Wish I could give out 1000 points to show my appreciation for all the great suggestions...
I'm glad I could help and thanks for the points.

Cheers,
Rene
@Bill:
Thanks for tweaking up!
Cheers,
Rene