I want to write a DOS batch file to delete old folders in a directory but keep the newest folder. Here is a sample of my folders under D:\myfolders\:
Jack_20110507 (previous day time-stamped folder)
Jack_20110508 (current day time-stamped folder)
James_20110507
James_20110508
Kenny_20110507
Kenny_20110508
...
I would like to delete all previous day time-stamped folders *_20110507, but keep all current day time-stamped folders *_20110508. New timestamped folders are created daily.
The script below will get the current local date in YYYYMMDD (courtesy of this answer).
It then loops through all the folders in a given directory (In my case this was a test sub folder beneath the folder containing the script) and checks the last 8 characters of the folder name. If they do not match today's date, it deletes the folder.
The /Q disables the confirmation for folder deletion. If you want to be prompted for confirmation before a folder is deleted, remove this.
#ECHO off & setlocal EnableDelayedExpansion
REM Get the local datetime
FOR /F "usebackq tokens=1,2 delims==" %%i IN (`wmic os get LocalDateTime /VALUE 2^>NUL`) DO IF '.%%i.'=='.LocalDateTime.' SET ldt=%%j
REM Set the datetime to YYYYMMDD format.
SET today=%ldt:~0,4%%ldt:~4,2%%ldt:~6,2%
REM For every file in the folder test:
FOR /D %%f IN (.\test\*) DO (
REM Store the folder name temproarily
SET folder=%%f
REM Get just the ending date part of the folder name
SET folderpart=!folder:~-8!
REM If it doesn't match todays date, delete the folder.
IF NOT !folderpart!==!today! RD /Q %%f
)
#ECHO ON
I wouldn't use a batch script for anything other than the very simplest stuff.
I recommend you look at a scripting language such as Python.
Related
I am stuck trying to build a batch file that will copy the newest files for particular naming conventions from a folder containing multiple naming conventions. For example the folder would contain the following types of file name, and i want the newest List01 and the newest List02:
C:\Import\List01####.txt modified date 01/07/2021 15:40
C:\Import\List01####.txt modified date 02/07/2021 15:40
C:\Import\List02####.txt modified date 03/07/2021 15:40
C:\Import\List02####.txt modified date 04/07/2021 15:40
the #### represents any random naming, the important bit is the List01 or List02 etc
I want the output to be a copy of the newest file for each list number:
C:\Results\List01####.txt modified date 02/07/2021 15:40
C:\Results\List02####.txt modified date 04/07/2021 15:40
So far I have the following that will find the newest file in the folder, but I'm not sure how to make it distinguish between List01 and List02 as I need the newest file of each list. I've tried findstr but can't get it to work.
#echo off
set source="C:\Import\"
set target="C:\Results"
for /f "delims=" %%I in ('DIR %source%\*.txt /A:-D /O:-D /B') DO COPY %source%\"%%I" %target% & echo %%I & GOTO :END
TIMEOUT 5
:END
I have read a similar post about this but couldn't figure out how to apply it to my specific situation.
I'm trying to create a folder in windows with current timestamp details and copy some folder to it. I tried as below:
bat 'for /f "tokens=2-4 delims=/ " %%i in ("%date%") do SET today_fname=%%i_%%j_%%k'
bat 'for /f "tokens=2-4 delims=/ " %%i in ("%date%") do md today_fname'
bat 'cd %today_fname%'
bat 'copy "C:/Program Files (x86)/Jenkins/workspace/jenkins Pipeline/application/bin/Debug/netcoreapp2.1/os/publish"'
It ends up creating a folder with a timestamp name and copying the folder contains to current directory instead of Cd to newly created folder
I'm trying to create a folder with a name 05_14_18_7_31 and copy the contains present in this location C:/Program Files (x86)/Jenkins/workspace/jenkins Pipeline/application/bin/Debug/netcoreapp2.1/os/publish to 05_14_18_7_31
Here is something you can try:
#echo off
rem Create datestamp:
set "datestamp=%date:~4,-8%_%date:~7,-5%_%date:~12,2%"
rem Request for me, if you are not using `dd/mm/yy` format, to provide another script for your occassion.
rem Create timestamp:
set "timestamp=%time:~0,2%_%time:~3,2%"
rem Create folder:
md %datestamp%_%timestamp%
xcopy /E "C:/Program Files (x86)/Jenkins/workspace/jenkins Pipeline/application/bin/Debug/netcoreapp2.1/os/publish" "%datestamp%_%timestamp%"
Hope this helps!
I use Dropbox to automatically upload all the photos/videos I take from my phone to a folder "My Dropbox\Camera Uploads". So this is full of files like:
2015-06-09 10.11.19.jpg
2015-09-11 09.28.46.mp4
I'd now like a batch file to move these to the correct folder (creating it if necessary) "..\Photos\Family\YYYY-MM" where YYYY-MM is the year and month of the photo (i.e. the first seven characters of the filename).
(It has to be a relative rather than absolute path as this Dropbox folder is shared across machines with XP, Vista and Windows 7 OSs, so the first part of the path is different on each.)
I've found similar batch files and tried to tweak them, but just can't get it to work. Many thanks for your help.
You can use this script (put it in a file with extension .bat) and start it:
#echo off
setlocal enabledelayedexpansion
rem For each file in your folder
for %%a in (*.*) do (
echo filename=%%a
rem check if the it is not our script
if "%%a" NEQ "%0" (
set foldername=%%a
set foldername=..\Photos\Family\!foldername:~0,7!
echo foldername=!foldername!
rem check if forlder exists, if not it is created
if not exist "!foldername!" mkdir "!foldername!"
rem Move (or change to copy) the file to directory
move "%%a" "!foldername!\"
)
)
There is a CLOSE solution to my problem, and everything is described in this question:
How to archive files older than 7 days with creating one archive for all files with same date?
The thing is, i need another solution similar to this but working for 7-Zip, this has to be coded in the bat file i believe since there is no -to7d switch in 7-Zip like there is in Winrar.
The Code right now ( Credit goes to #Mofi for creating this ):
#echo off
setlocal EnableExtensions EnableDelayedExpansion
rem Define the directories to use for backup task.
set "LogDirectory=D:\tet\Web3811\Web3811\log"
set "BakDirectory=D:\tet\Web3811\Web3811\LogsBackup"
rem Get all file names in log directory into a list file sorted by last
rem modification date with oldest file at top and newest at bottom.
rem Note: /S is important to get the file names with complete path.
dir "%LogDirectory%\*" /A-D /B /OD /S /TW 1>"%BakDirectory%\LogFiles.lst" 2>nul
rem Jump to clean up stage if no file found in the log directory.
if errorlevel 1 goto :CleanUp
rem Delete list file for all files with same day if file exists
rem for example from a previous execution of this batch file
rem which was terminated manually by a user during execution.
if exist "%BakDirectory%\DayFiles.lst" del "%BakDirectory%\DayFiles.lst"
set LastDate=none
for /F "usebackq delims=" %%F in ( "%BakDirectory%\LogFiles.lst" ) do (
set FileTime=%%~tF
rem Get just file date from file time in format DD-MM-YYYY.
rem The file time string format depends on date and time
rem format definition in Windows language settings.
rem Therefore the line below must be adapted if date format
rem is whether DD.MM.YYYY nor DD-MM-YYYY nor DD/MM/YYYY.
set FileDate=!FileTime:~6,4!-!FileTime:~3,2!-!FileTime:~0,2!
rem Is the last modification date of this file different
rem to last modification date of the previous file?
if not "!FileDate!"=="!LastDate!" (
rem Nothing to archive on first difference.
if not "!LastDate!"=="none" call :ArchiveLogs
rem Exit loop if RAR has not archived any file which means
rem all other files are modified within the last 7 days.
if "!LastDate!"=="ExitLoop" goto CleanUp
rem Start creating a new list.
set LastDate=!FileDate!
)
rem Append name of this file with path to current day list.
echo %%F>>"%BakDirectory%\DayFiles.lst"
)
rem Jump to clean up stage if no list file with files to archive.
if not exist "%BakDirectory%\DayFiles.lst" goto CleanUp
rem Otherwise with no log file created or modified within
rem the last 7 days, but at least one older file exists
rem nevertheless, archive all those files in list file.
call :ArchiveLogs
:CleanUp
del "%BakDirectory%\LogFiles.lst"
endlocal
goto :EOF
:ArchiveLogs
"C:\Program Files (x86)\7-Zip\7z" -sdel a -mmt -mx3 -tzip "%BakDirectory%\!LastDate!_Logs.zip" "#%BakDirectory%\DayFiles.lst"
if errorlevel 10 set LastDate=ExitLoop
del "%BakDirectory%\DayFiles.lst"
Basically there just needs to be added a check that check if Modified date = older than 7 days.
i'm not sure how to implement this, since once you run the :ArchiveLogs 7-Zip will just take EVERYTHING in that folder and as far as i can see there are no switches to check for that.
I believe we have to do something like this:
Code to check if file has a modification date older than 7 days & save that file name in a value.
:ZipOnlyafter7days
For:
"C:\Program Files (x86)\7-Zip\7z" -sdel a -mmt -mx3 -tzip "%BakDirectory%!LastDate!_Logs.zip" "#%BakDirectory%\ Filename_Value "
You should use robocopy with the /maxage:7 option to copy relevant files to a temp folder, and then compress all the files using 7zip.
The below works for files with a number of days old from a batch file
forfiles /P (SOURCE_folder) /S /M *.* /D -(number of date old) /C "cmd /C 7Z.exe a "Archive.ZIP #file"
I am just working to try and get the date correct.
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.