I am looking for a way to zip folders based on a timespan of their lastmodified date and remove them afterwards
the structure is as follows
Folder_1 01.01.2012 12:00
- sub1
- sub2
- file1
- file2
Folder_2 01.01.2012 12:02
...
Folder_20202 05.05.2012 03:00
I want now:
to select all folders that are 3 months older than this month
(e.g. lastmodified is february when current is may). An importand point is that I want to use 1st to last of month and not -90 days
then zip the selected folders with all subfolders and files contained into one february2012.zip
delete the originals of the (now) zipped files
my best idea so far is to use forfiles.exe (which takes only one date), use a generated date (1st day of 3 month ago and use the older than modifier) and create a resultextfile. Then use the resultfile as import for 7zip.exe and somehow loop over the file and delete the folders afterwards (for part 2&3, I have not yet a working code)
-- UPDATE --
At the moment I am experimenting with:
FORFILES /P H:\Temp\2zip /M O* /D -31.4.2012 /C "cmd /c C:\Program Files (x86)\7-Zip\7z.exe a -t7z H:\temp\x2.zip #path
which seems to work - but just very slowly (I guess reason is mapped drive -> 3h for 150MB)
Be careful when working with last modified date of folders. On a FAT file system, the time stamp does not change when the contents of the folder change.
On a NTFS file system, the last modified date is updated whenever a file or folder is created or deleted within the folder. But it is not updated if a file is modified, or if a file/folder is created or deleted in a sub folder.
If you still want to move forward with your plan, then your basic strategy is pretty solid. Windows batch has very weak support for dealing with dates, so there is not much room for improvement.
The best way to parse the current date (and time if you want it) regardless of locale is to use WMIC:
for /f "skip=1" %%A in ('wmic os get localdatetime') do (
set currentDateTime=%%A
goto :exitLoop
)
:exitLoop
set year=%currentDateTime:~0,4%
set month=%currentDateTime:~4,2%
You should be able to use a move option of 7zip such that you don't need to delete the folder afterwards.
You should be able to eliminate the need for a temp file by processing the results of the FORFILES with a FOR /F. Or better yet, you may be able to specify the appropriate 7zip command with the FORFILES /C option.
Related
I tried to create a batch script which will move a folder created on a previous day from a directory to another.
I've looked at all the trends and tried to do it myself, and I managed to do something, but it still doesn't do what I would like.
In a directory, I will always have 2 folders. Every day I need to go and copy the folder created on the previous day to the new location at 3 am in the morning. I've tried all the option with the MAXAGE, MINAGE, MAXLAD, and MINLAD but probably I don't understand how this works!
#echo off
/MINAGE:1 :: MINimum file AGE - exclude files newer than 1 days/date.
set MyLogFile=%date%
set MyLogFile=%MyLogFile:/=-%
robocopy /log+:"C:\Users\Desktop\Test\%mylogfile%.txt" /TEE C:\Users\Desktop\Test\try1\n1 C:\Users\Desktop\Test\try2\n2 /MOVE /E /MINAGE:1
robocopy /log+:"C:\Users\Desktop\Test\%mylogfile%.txt" /TEE C:\Users\Desktop\Test\try3\n3 C:\Users\Desktop\Test\try4\n4 /MOVE /E /MINAGE:1
At the moment it moves all the files from try1/n1 to try2/n2 no matter how old or new is the folder.
The expected result would be from try1/n1 in which I have 2 folders (one created yesterday and one today) to move into try2/n2 only the folder created yesterday!
I have two folders called Roads and Kerbs. I want to copy both folders (keeping the folder name) into a backup folder with the current year/month as the folder name.
Example: The backup folder name will be 201812 and if I open it the two folders Roads and Kerbs will be under it. I want to create a batch file with xcopy to do this function for me.
The current code only opens a folder named 01 and only copies the folder content. I want the month/year and then the two folders under it with their content.
#echo off
set curr_date=%DATE:~10,2%-%DATE:~7,2%
mkdir "C:\Roads_backup\%curr_date%"
xcopy "C:\Roads" "C:\Roads_backup\%curr_date%" /D/S/H/V/C/F/K
How to copy the two folders to new directory with current year and month in directory name?
CMD is Horrible at Dates
For anything of any complexity whatsoever, I'd avoid using %DATE% and %TIME% in favor of not reinventing the wheel. PowerShell comes standard (though with different versions) on every Windows platform released in the past 10 years, and uses a reasonably full-featured date/time library.
FOR /F "usebackq" %%d IN (`PowerShell -NoProfile -ExecutionPolicy Bypass -Command "Get-Date -UFormat '%%Y%%m'" ^<NUL`) DO SET "STAMP=%%~d"
This will set the envvar STAMP to the formatted date string, controlled by the -UFormat parameter. It won't matter what the computer's locale or language is, and it'll work on anything with PowerShell (standard on Win7 and beyond).
It is a little wordy, but you can also easily copy/paste it without having to recalculate all the string offsets needed to carve up the values in %DATE% and %TIME% every time you want format the current date.
You can also do the same thing with dates other than the current one, as well as subtract timespans from the current date to get things like "a week ago"—something excruciatingly painful to do with pure batch/CMD alone.
Copying Directories
You'll probably want to use the /I (target name is a dir) parameter of xcopy as well as specify the target directory name to use (otherwise, xcopy will put the contents of Roads into the target directory without creating a directory named Roads).
xcopy "C:\Roads" "C:\Roads_backup\%STAMP%\Roads" /I/D/S/H/V/C/F/K
I'm not sure if you need /D if you're always going to be creating new dirs, since that means "only copy newer files."
I'm building batch files to (1) move directories older than 120 days to an archive location and (2) then eventually delete those folders from the archive location when they are 4 years old.
The names of the directories are in CCYYMM format (201601). The business rule is to move/delete based on the date in the directory name, not the modify or create date.
This is similar to Batch file logic to delete files based on date in filename, but since my scenario is for directories, not files, not certain if this would work, or how to modify for directories. The FOR command only appears to work for files(?)
Is there a method to loop through directories and perform a move or rmdir command in a batch file, comparing the month/year in the name to current month/year?
I did find that FORFILE works for directories based on modified date, but requirements are to use directory name.
Thanks for your consideration!
Edit 20160817
Since the directories are year/month labeled (201601 for January 2016), I'm taking the current year month (201608) and subtracting the directory value. For example 201608 - 201601 = 7. Then the batch would move any folder that has a difference of 4 or greater to meet the business requirements, using the FOR /D and only looking at directories beginning with 2:
#echo off
setlocal EnableDelayedExpansion
SET tempDATE=%DATE:~10,4%%DATE:~4,2%
for /d %%a in ("2*") do (
set /a numberOld=tempDATE - %%a
if !numberOld! geq 4 move /Y %%a ArchiveFolder
)
Using the same type of logic, I'm using 400 as the test value for the remove/delete directory script.
Appreciate everyone's insight.
I have a program that creates a backup every 30 minutes, but does not delete older files. I am looking to make a script that will run on task scheduler that will look in the folder that is created by the program. It creates folder by date as follows /year/month/day/*name of file.zip. I have done a little research and come up with
#ECHO OFF
for /f "usebackq delims== tokens= 2" %%i in ( WMIC OS GET localdatetime /format:value ) do set localTime=%%i
set "YYYY=%localTime:~0,4%"
set "M=%localTime:~4,1%"
set "MM=%localTime:~5,1%"
set "D=%localTime:~6,1%"
set "DD=%localTime:~7,1%"
if %M%==0 set M=
if %D%==0 set D=
cd /d "~%~dp0"
FOR /F "tokens=*" %%X IN ('dir .\%YYYY%\%M%%MM%\%D%%DD%\Backup-serversave-%YYYY%-%M%%MM%-%D%%DD%--*.zip /b /o:-d') DO set FILENAME=%%~X
rem FILENAME now contains the last element
if "%FILENAME%" neq "" DEL "%FILENAME%"
pause
This script looks in the folder by todays date and than should delete the file that is oldest in the folder. But every time I run it, all I get is a "cannot find file" and it tells me the exact file that it says it can't find. So I need a little help to make it work. It would be also great if there is any way to make it only delete after five files are in the folder. If anyone can help me that would be amazing.
Update. Got a good answer but need a little more help. If anyone out there can find a way to make it delete yesterdays folder at the change of the day that would be amazing I am looking all over and so far have found nothing.
You did already a quite good job on writing the batch file, but made some small mistakes.
Using in first line ECHO ON helped to find those mistakes.
The following lines with some corrections for the batch file work.
#ECHO OFF
for /f "usebackq delims== tokens=2" %%i in ( `WMIC OS GET localdatetime /format:value` ) do set localTime=%%i
set "YYYY=%localTime:~0,4%"
set "M=%localTime:~4,1%"
set "MM=%localTime:~5,1%"
set "D=%localTime:~6,1%"
set "DD=%localTime:~7,1%"
if %M%==0 set M=
if %D%==0 set D=
cd /d "%~dp0"
for /F "usebackq tokens=* skip=5" %%X in ( `dir .\%YYYY%\%M%%MM%\%D%%DD%\Backup-serversave-%YYYY%-%M%%MM%-%D%%DD%--*.zip /b /o:-d` ) do del .\%YYYY%\%M%%MM%\%D%%DD%\%%X
pause
No file was not deleted ever because you used command dir to find the ZIP files in a subdirectory. The name of a found file was referenced with %%X, but without the path to this file. As the batch file did not change into the directory on which dir searched for the ZIP files, command DEL could not find the file to delete in the current working directory.
The first 5 lines returned by command dir containing the 5 newest files according to last modification date are ignored by using skip=5. Therefore only files with todays date in name and older than the first 5 files in directory listing are deleted and the newest 5 files are kept.
There was also a mistake in line with command cd and some other small mistakes all found by using ECHO ON in first line.
Deleting the previous day folders is difficult if the batch file should find out automatically which folders should be deleted and which folders should be kept.
Here is a solution which makes this task simple and which can be appended to the other lines in my other answer for deleting the older backup files.
if exist .\%YYYY%\%M%%MM%\%D%%DD%\Backup-serversave-%YYYY%-%M%%MM%-%D%%DD%--*.zip (
md TempBackup
copy /V .\%YYYY%\%M%%MM%\%D%%DD%\*.zip TempBackup >nul
for /F "usebackq" %%D in ( `dir /AD /B 20*` ) do rd /S /Q %%D
md %YYYY%\%M%%MM%\%D%%DD%
copy /V TempBackup\*.zip %YYYY%\%M%%MM%\%D%%DD% >nul
rd /S /Q TempBackup
)
First, a check is made if there are already ZIP files today stored to prevent deleting older backups if not at least one backup is created today.
Next a directory with name TempBackup is created into which are copied the currently existing backup files created today.
Then a dir command is executed which lists only the names of the directories starting with 20. Currently this is just the directory 2014, but on 2015-01-01 it will be additionally 2015. All those directories are recursively and silently deleted.
Next the directory tree for today is recreated and the ZIP files are copied back into this directory.
Finally the temporary backup directory for the ZIP files is deleted, too.
I'm wondering now why using a directory with current year as name containing a directory with current month as name containing a directory with current day of month as name if the ZIP files itself contain also year, month and day in name, and all ZIP files except the last 5 ZIP files saved today should be deleted?
It would be perhaps easier to manage to create all ZIP files in same directory and delete all ZIP files except the last 5 according to last modification date.
On the other hand the management with directories make it possible to keep backups from several days like one month and just delete the backup of previous month from time to time either manually or automatically for example on 15th of every month.
So I've got a batch file that backs up a folder to my Google Drive directory, like so:
C:\Program Files\WinRAR\rar.exe a -r "D:\Google Drive\Saves Backup\%DATE%.rar" "D:\Documents\My Games\"
This makes a file called 30-Sep-12.rar (being run today) in the appropriate folder.
However, my question is this: Is there some way to go through said folder (D:\Google Drive\Saves Backup) and delete backups that are more than a week old, as determined by the filename?
Why must you use the date embedded within the file name? The last modified date should be the same as the date embedded in the file name as long as the backup has not been modified since it was created.
FORFILES is one of the few Windows utilities that conveniently works with date arithmetic. Type FORFILES /? from the command line to get help on its usage.
forfiles /p "D:\Google Drive\Saves Backup" /m "*.rar" /d -7 /c "cmd /c del #path"
If you have a risk that someone could modify a backup, thus changing the last modified date, then the above will not work. Parsing and comparing dates is a pain in batch. You would be better off using VBScript.