根据文件名日期删除超过180天的文件

时间:2017-11-02 17:59:19

标签: batch-file

我想写一个批处理文件(适用于Windows命令提示符),它会删除特定文件夹中超过180天的所有文件,但会根据文件名中写入的日期< / strong>而不是文件的修改日期。

以下是文件在文件夹中的命名方式,它们都遵循以下特定模板: Backup_YYYYMMDDHHMMSS_FileName.ext

我在不同的网站上发现了多个例子,但它们都是指文件的修改日期。

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

此批处理文件使用强力方法使用XCOPY命令使用一点点技巧计算当天减去180天的时间。通过将日期转换为批处理文件中的朱利安日期,有更好更快捷的方法来获取减去日期。但是我总是使用这个,因为我理解它,而且通常只需要用我所有的工作回来一两个星期。

Powershell或任何其他Windows脚本语言(如Jscript或Vbscript)将是获取日期的更好解决方案。使用Powershell,您理论上可以使用一行代码从批处理文件中调用它,以便在一瞬间内获得日期。

PowerShell -Command "&{((Get-Date).AddDays(-180)).ToString('yyyyMMdd')}"

无论如何,这里是纯批处理文件解决方案。将文件夹变量设置为文件所在的位置。当您对屏幕上的输出感到满意时,请从代码的这一行中删除ECHO一词:echo del "%%G_%%H_%%I"。这只是测试的安全预防措施。删除回显后,它将删除文件。

@echo off
setlocal
set "folder=C:\some folder\sub folder"

REM set the number of days to substract
SET DAYS=180

REM Call function to check if the date is valid.
CALL :validdate "%days%" subdate
echo Older than: %subdate%
pushd "%folder%"

REM Get a list of the files
REM file pattern is: Backup_YYYYMMDDHHMMSS_FileName.ext
set "search=[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]"
FOR /F "tokens=1,2* delims=_" %%G IN ('dir /a-d /b Backup_*_*.* 2^>nul ^|findstr /I /R /C:"^backup_%search%_*.*"') DO (
    setlocal enabledelayedexpansion
    set "fdate=%%H"
    set "fdate=!fdate:~0,8!"
    IF !fdate! lss %subdate% echo del "%%G_%%H_%%I"
    endlocal
)
popd
pause

endlocal
GOTO :EOF

:validdate
setlocal
set "day=%~1"
set rand=%random%
md "%temp%\dummy%rand%\empty%rand%"

REM Get todays date
for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"

REM set year month and day into its own variables.
set /a y=%dt:~0,4%
set /a m=1%dt:~4,2%
set /a d=1%dt:~6,2%

:loop
if "%day%"=="0" (
    rd /s /q "%temp%\dummy%rand%"
    endlocal &set "%~2=%y%%m:~-2%%d:~-2%"
    GOTO :EOF
)
set /a d-=1

if %d% lss 101 (
    set d=131
    set /a m-=1

    if %m% lss 101 (
        set m=112
        set /a y-=1
    )
)

xcopy /d:%m:~-2%-%d:~-2%-%y% /t "%temp%\dummy%rand%\empty%rand%" "%temp%\dummy%rand%" >nul 2>&1 && (set /a day-=1 & goto loop) || goto loop

GOTO :EOF

这是我在我的系统上使用它的一个例子。我首先向您展示所有备份文件的目录列表,然后运行批处理文件以显示它将删除哪些文件以及减去的日期。

C:\BatchFiles\DATE_TIME_FUNCTIONS>dir /b backup*
Backup_20170504013002_FileName.txt
Backup_20170505093002_FileName.txt
Backup_20170506113002_FileName.txt
Backup_20170507123002_FileName.txt

C:\BatchFiles\DATE_TIME_FUNCTIONS>DeleteFiles.bat
Older than: 20170506
del "Backup_20170504013002_FileName.txt"
del "Backup_20170505093002_FileName.txt"
Press any key to continue . . .

现在我的减法日期函数会略微减慢,因为它使用循环来获取减去的日期。您需要减去运行所需时间的天数就越多。虽然在这个阶段,只是减去回到最后一个闰日真的不是那么多时间。在我的电脑上只有大约5秒钟。

但是这段代码使用了一个很好的算法来使用julian日期来进行日期数学运算。它在计算日期时比我以前的代码快得多。

@echo off
setlocal

Call :GetDateTime Year Month Day
Call :SubtractDate %Year% %Month% %Day% -613 Ret

echo subdate: %Ret%
pause
GOTO :EOF

:SubtractDate Year Month Day <+/-Days> Ret
::Adapted from DosTips Functions::
setlocal & set a=%4
set "yy=%~1"&set "mm=%~2"&set "dd=%~3"
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
if %a:~0,1% equ + (set /a JD=%JD%+%a:~1%) else set /a JD=%JD%-%a:~1%
set /a L= %JD%+68569,     N= 4*L/146097, L= L-(146097*N+3)/4, I= 4000*(L+1)/1461001
set /a L= L-1461*I/4+31, J= 80*L/2447,  K= L-2447*J/80,      L= J/11
set /a J= J+2-12*L,      I= 100*(N-49)+I+L
set /a YYYY= I, MM=100+J, DD=100+K
set MM=%MM:~-2% & set DD=%DD:~-2%
set ret=%YYYY: =%%MM: =%%DD: =%
endlocal & set %~5=%ret%
exit /b

:GetDateTime Year Month Day Hour Minute Second
@echo off & setlocal
for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
set "YY=%dt:~2,2%" & set "YYYY=%dt:~0,4%" & set "MM=%dt:~4,2%" & set "DD=%dt:~6,2%"
set "HH=%dt:~8,2%" & set "Min=%dt:~10,2%" & set "Sec=%dt:~12,2%"
( ENDLOCAL
   IF "%~1" NEQ "" set "%~1=%YYYY%" 
   IF "%~2" NEQ "" set "%~2=%MM%" 
   IF "%~3" NEQ "" set "%~3=%DD%"
   IF "%~4" NEQ "" set "%~4=%HH%" 
   IF "%~5" NEQ "" set "%~5=%Min%"
   IF "%~6" NEQ "" set "%~6=%Sec%"
)
exit /b