如何在不使用forfile的情况下删除N天之前的所有目录(和内容)?

问题描述:

我按照批处理文件中的答案删除了N天以上的文件夹(特定文件夹除外).

是否可以使用 forfiles 命令删除所有早于N天但没有N天的文件夹(及其内容)?

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

我的问题的原因是我的计算机具有旧的DOS版本,并且可能没有命令 forfiles .

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

这是一个批处理文件,不使用命令 forfiles 来删除 C:\ Temp 递归中的所有文件夹日期早于7天.

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.

因此,它将在2015-02-08删除所有日期直到2015-01-31的文件夹,同时保留所有从2015-02-01开始的文件夹.

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.

请注意!

日期和时间字符串的格式取决于Windows语言设置.在以下第一个 FOR 循环中,分配给环境变量 Day Month Year 的定界符和标记的顺序必要时,必须将 GetSeconds 调整为本地日期/时间格式.

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.

注意::还有一个 echo 可以命令 rd 来输出要递归删除的文件夹.在测试运行后,必须删除 echo 以进行验证,以真正删除文件夹.

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

此批处理文件是我的答案针对最喜欢的问题批处理文件以删除早于N天的文件,该文件将忽略时间并仅评估每个文件夹的日期.

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.

如果环境变量 DATE 中的日期格式与 %%〜tD 上的命令 FOR 使用的日期格式不同,则有必要进行调整环境变量的日期字符串.

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.

例如,将%DATE%扩展为 Sun 02/08/2015 ,而将 %%〜tD 扩展为 02/2015年8月8日下午9:29 上面的代码可用于将第4行修改为:

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%"

这导致仅将 02/08/2015 传递给子例程-日期字符串,不包含工作日缩写的3个字母和空格字符.

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%"

现在,日期字符串中的最后10个字符将传递给函数 GetSeconds ,因此环境变量 DATE 的日期字符串是否带有工作日都没有关系因为日期和月份始终按预期的顺序显示两位数,即格式为 dd/mm/yyyy dd.mm.yyyy .

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.