Page 1 of 1

Delete files AND folder over 30 days old - is this the correct approach?

Posted: 06 Aug 2017 11:10
by SIMMS7400
Hi Folks -

I need to run a script that purges files and folders every 30 days.

Here is what I have:

Code: Select all

@ECHO OFF 


set FDMEE_DIR=C:\FDMEE_PROJ\INBOX
set MAX_DAY=30

forfiles -p "%FDMEE_DIR%" -s -m *.* -d -%MAX_DAY% -c "cmd /c del @path" >nul 2>&1
forfiles -p "%FDMEE_DIR%" -d -%MAX_DAY% -c "cmd /c IF @isdir == TRUE rd /S /Q @path" >nul 2>&1


is the above the correct approach or are there better options? The above is for Windows 7 or higher. Is there a Version agnostic approach? Thanks!

Thanks!

Re: Delete files AND folder over 30 days old - is this the correct approach?

Posted: 06 Aug 2017 11:40
by elias
Hello,

1)
There's one case in your approach that might yield an unexpected result:

What if a directory that you are removing contains files not older than 30 days?

So the directory is 30 days old but not some of the files inside it. Do you really want to remove that folder?

2)
To stop using forfiles.exe , what about trying to parse the output of the "dir <filename>" command?

The first token is the date, so it should be easy to parse that out.

If you need more reference on that, simply scroll up in this page to see the list of articles on the tokenizing topic.

--
Elias

Re: Delete files AND folder over 30 days old - is this the correct approach?

Posted: 06 Aug 2017 14:55
by aGerman
Unfortunately developing a downward-compatible batch solution isn't as simple as Elias said.
Date formats are localized. They differ in the order of year, month and day, and they differ in their separator. Also the number of tokens in the output of DIR differs depending on the time format (additional token for AM or PM for a 12 hour clock).
Furthermore there is no simple calculation for the difference between dates because batch has no DateTime type. The fact that months don't have the same length and additional differences in leap years don't make things easier.

Proof of concept:

Code: Select all

@echo off &setlocal

call :init_international_settings
call :split_date "%date:* =%" y m d
call :date2jdate jd %y% %m% %d%


for /d %%i in (*) do (
  set "fname=%%~i"
  call :split_date "%%~ti" fy fm fd
  setlocal EnableDelayedExpansion
  call :date2jdate fjd !fy! !fm! !fd!
  set /a "dif=jd-fjd"

  REM This line only lists the date difference in days of the folders
  echo !dif! !fname!

  endlocal
)

pause
exit /b


::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

:init_international_settings
for /f "tokens=1,2*" %%a in ('reg query "HKCU\Control Panel\International"^|findstr /i "\<[is]Date\>"') do set "%%a=%%c"
exit /b

:split_date
for /f "tokens=1-3 delims=%sDate% " %%a in ("%~1") do (
  if %iDate%==0 (set /a %~3=100%%a%%100,%~4=100%%b%%100,%~2=10000%%c%%10000) else (
  if %iDate%==1 (set /a %~4=100%%a%%100,%~3=100%%b%%100,%~2=10000%%c%%10000) else (
  if %iDate%==2 (set /a %~2=10000%%a%%10000,%~3=100%%b%%100,%~4=100%%c%%100)
)))
exit /b

:date2jdate JD YYYY MM DD -- converts a gregorian calender date to julian day format
::                        -- JD   [out] - julian days
::                        -- YYYY [in]  - gregorian year, i.e. 2006
::                        -- MM   [in]  - gregorian month, i.e. 12 for december
::                        -- DD   [in]  - gregorian day, i.e. 31
:$reference http://aa.usno.navy.mil/faq/docs/JD_Formula.html
:$created 20060101 :$changed 20080219 :$categories DateAndTime
:$source http://www.dostips.com
SETLOCAL
set "yy=%~2"&set "mm=%~3"&set "dd=%~4"
set /a "yy=10000%yy% %%10000,mm=100%mm% %% 100,dd=100%dd% %% 100"
if %yy% LSS 100 set /a yy+=2000 &rem Adds 2000 to two digit years
set /a JD=dd-32075+1461*(yy+4800+(mm-14)/12)/4+367*(mm-2-(mm-14)/12*12)/12-3*((yy+4900+(mm-14)/12)/100)/4
ENDLOCAL & IF "%~1" NEQ "" (SET %~1=%JD%) ELSE (echo.%JD%)
EXIT /b

- The :init_international_settings routine initializes two variables (iDate and sDate) that are read from registry and indicate the order and separator of a date string.
- The :split_date routine splits the passed date string depending on iDate and sDate.
- I picked up :date2jdate from the DosTips function library. It calculates the passed date to a continuous count of days since a certain date.

I used a FOR /D loop that processes folders. Use a simple FOR loop for files.
The code only lists the calculated age and the related folder. Just check if !dif! gtr 30 ...

~~~~~~~~~~

Aacini developed little 3rd party utilities. StdDate.exe could make things easier for you. See
viewtopic.php?f=3&t=3428#p17610
The package is attached to the initial post.


Steffen