YWATFA
YWATFA

Reputation: 91

How to delete all directories (and contents) older than N days without usage of forfiles?

I followed the answer on Batch file to delete folders older than N days except specific ones.

Is there a way to delete all folders (and their contents) older than N day BUT WITHOUT using forfiles command?

The reason for my question is that my machine has an old DOS version and may not have the command forfiles.

Upvotes: 1

Views: 479

Answers (1)

Mofi
Mofi

Reputation: 49086

Here is a batch file not using command forfiles to delete all folders in C:\Temp recursive which have a date older than 7 days.

So it deletes on 2015-02-08 all folders with a date up to 2015-01-31 while keeping all folders with a date starting from 2015-02-01.

Attention please!

The format of date and time strings depends on Windows language settings. The delimiters and the order of tokens assigned to the environment variables Day, Month and Year in first FOR loop of GetSeconds must be adapted to local date/time format if necessary.

Note: There is an echo left to command rd to just output which folders would be deleted recursive. echo must be removed after a test run for verification to really delete the folders.

@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Get seconds since 1970-01-01 for current day.
call :GetSeconds "%DATE%"
rem Subtract seconds for eight days from seconds value.
set /A "LastWeek=Seconds-8*86400"

rem For each subdirectory of C:\Temp get date (without seconds)
rem and determine the number of seconds since 1970-01-01 for
rem this date/time. The directory can be deleted recursive
rem if seconds value is lower than the value calculated above.

for /D %%I in ("C:\Temp\*") do (
    call :GetSeconds "%%~tI"
    set "FullFolderName=%%I"
    setlocal EnableDelayedExpansion
    if !Seconds! LEQ %LastWeek% echo rd /S /Q "!FullFolderName!"
    endlocal
)
endlocal
goto :EOF

:GetSeconds
for /F "tokens=1-3 delims=,-./: " %%A in ("%~1") do (
    rem For English US date MM/DD/YYYY or M/D/YYYY
    set "Day=%%B" & set "Month=%%A" & set "Year=%%C"
    rem For German date DD.MM.YYYY or English UK date DD/MM/YYYY
    rem set "Day=%%A" & set "Month=%%B" & set "Year=%%C"
)

if "%Month:~0,1%"  == "0" if not "%Month:~1%"  == "" set "Month=%Month:~1%"
if "%Day:~0,1%"    == "0" if not "%Day:~1%"    == "" set "Day=%Day:~1%"

set /A "Index1=Year-1979"
set /A "Index2=Index1-30"

if %Index1% LEQ 30 (
    for /F "tokens=%Index1% delims= " %%Y in ("3652 4018 4383 4748 5113 5479 5844 6209 6574 6940 7305 7670 8035 8401 8766 9131 9496 9862 10227 10592 10957 11323 11688 12053 12418 12784 13149 13514 13879 14245") do set "Days=%%Y"
    for /F "tokens=%Index1% delims= " %%L in ("Y N N N Y N N N Y N N N Y N N N Y N N N Y N N N Y N N N Y N") do set "LeapYear=%%L"
) else (
    for /F "tokens=%Index2% delims= " %%Y in ("14610 14975 15340 15706 16071 16436 16801 17167 17532 17897 18262 18628 18993 19358 19723 20089 20454 20819 21184 21550 21915 22280 22645 23011 23376 23741 24106 24472 24837") do set "Days=%%Y"
    for /F "tokens=%Index2% delims= " %%L in ("N N Y N N N Y N N N Y N N N Y N N N Y N N N Y N N N Y N N") do set "LeapYear=%%L"
)
if "%LeapYear%" == "N" (
    for /F "tokens=%Month% delims= " %%M in ("0 31 59 90 120 151 181 212 243 273 304 334") do set /A "Days+=%%M"
) else (
    for /F "tokens=%Month% delims= " %%M in ("0 31 60 91 121 152 182 213 244 274 305 335") do set /A "Days+=%%M"
)
set /A "Days+=Day-1"
set /A "Seconds=Days*86400"
goto :EOF

This batch file is a variant of my answer on favorite question Batch file to delete files older than N days which ignores the time and evaluates just the date of each folder.

If date format in environment variable DATE is different to date format used by command FOR on %%~tD it is necessary to adapt the date string of the environment variable.

For example with %DATE% expands to Sun 02/08/2015 while %%~tD expands to 02/08/2015 09:29 PM the above code can be used with modifying line 4 to:

call :GetSeconds "%DATE:~4%"

This results in passing to subroutine just 02/08/2015 - the date string without the 3 letters of weekday abbreviation and the separating space character.

Alternatively following could be used as fourth line in above code:

call :GetSeconds "%DATE:~-10%"

Now the last 10 characters from date string are passed to function GetSeconds and therefore it does not matter if date string of environment variable DATE is with or without weekday as long as day and month are always with 2 digits in expected order, i.e. in format dd/mm/yyyy or dd.mm.yyyy.

Upvotes: 1

Related Questions