Sal Sorice
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?
for /f "tokens=1-5 delims=/ " %%d in ("%date%") do rename "F:\Backups\Images\DriveD_
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?
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.
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("Script ing.FileSy stemObject ")
Set objArgs = WScript.Arguments
strFile= objArgs(0)
WScript.Echo objFS.GetFile(strFile).Dat eCreated
WScript.Echo objFS.GetFile(strFile).Dat eLastModif ied
WScript.Echo objFS.GetFile(strFile).Dat eLastAcces sed
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\Imag es\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.
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("Script
Set objArgs = WScript.Arguments
strFile= objArgs(0)
WScript.Echo objFS.GetFile(strFile).Dat
WScript.Echo objFS.GetFile(strFile).Dat
WScript.Echo objFS.GetFile(strFile).Dat
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\Imag
set CurrDir=%~dp0
set CurrDir=%CurrDir:~0,-1%
if exist "%TargetFile%" (
cscript //NoLogo "%CurrDir%\GetFileDate.vbs
) 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.
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
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
~bp
What do you see when you enter the following command in DOS:
echo %date%
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
@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_
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.
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
(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?
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:
May need some tweaking
Cheers,
Rene
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"
May need some tweaking
Cheers,
Rene
Here is my fixed version
Hoping that helps!
Cheers,
Rene
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
ASKER
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.
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
If scion111 finds my approach to be good, feel free to optimize it. I prefer learning than points...
Cheers,
Rene
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Sorry for the delay everyone - down server yesterday :-(
Will test today and advise. Thanks again for all the help!
Will test today and advise. Thanks again for all the help!
ASKER
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...
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
Cheers,
Rene
@Bill:
Thanks for tweaking up!
Cheers,
Rene
Thanks for tweaking up!
Cheers,
Rene
Good luck - Michael