我知道删除旧文件的命令。如何使用 forfiles 命令删除 12 小时前的文件
我在 .bat 文件中使用 forfile 命令
好吧,我为你辛苦了……
SETLOCAL ENABLEDELAYEDEXPANSION
REM 1: Parse date time string
FOR /F "TOKENS=1-5 DELIMS=/-:,. " %%i IN ("%DATE% %TIME%") DO (
SET year=%%k
SET month=%%j
SET day=%%i
SET hour=%%l
SET minute=%%m
)
REM 2: Subtract 12 hours, handling day wrap including leap year.
SET /A hour-=12
IF %hour% LSS 0 SET /A hour+=24 & SET /A day-=1
IF %day% LSS 1 (
SET /A month-=1
IF !month! LSS 1 SET /A month+=12 & SET /A year-=1
FOR %%m IN (1 3 5 7 8 10 12) DO IF %%m == !month! SET /A day+=31
FOR %%m IN (4 6 9 11) DO IF %%m == !month! SET /A day+=30
IF !month! == 2 (
SET /A day+=28
SET /A y4=!year! %% 4
IF !y4! == 0 (
SET /A y400=!year! %% 400
IF !y400! == 0 (
SET /A day+=1
) ELSE (
SET /A y100=!year! %% 100
IF NOT !y100! == 0 SET /A day+=1
)
)
)
)
REM 3: Normalize string for later string comparison
CALL :norm_datetime "%day%-%month%-%year% %hour%:%minute%" limit_datetime
REM 4: List file, parse file sate time and delete on comparison verified.
FOR %%f IN (*.*) DO (
CALL :norm_datetime "%%~tf" file_datetime
IF !file_datetime! LSS %limit_datetime% ECHO DEL %%f
)
ENDLOCAL
GOTO :EOF
REM 4: function to normalize date time string
REM norm_datetime "time string" output_environment_variable
REM time string format must be d-m-y-h-m[-...], where - is any valid separator.
REM output will be YYYYMMDDTHHMM
:norm_datetime
FOR /F "TOKENS=1-5 DELIMS=/-:,. " %%i IN ("%~1") DO (
SET year=0000%%k
SET month=00%%j
SET day=00%%i
SET hour=00%%l
SET minute=00%%m
)
SET %2=%year:~-4%%month:~-2%%day:~-2%T%hour:~-2%%minute:~-2%
GOTO :EOF
检查代码注释中的预期日期和时间格式。
请注意,日期和时间格式取决于系统,因此该代码必须适用于不同的系统。
在 Windows 批处理中处理日期和时间是多么困难,这太荒谬了。我怀疑 PowerShell 可能更好,但我真的不知道。
我编写了一个方便的混合 JScript/批处理实用程序,它可以进行日期和时间算术和格式化。它可用于确定 12 小时前的日期和时间,并将其格式化为几乎任何需要的格式。该实用程序适用于从 XP 开始的任何 Windows 平台。它是纯脚本,因此不需要下载或安装任何 exe 文件。getTimestamp.bat 可在此处获得。实际的实用程序在帖子的底部,它在脚本中包含大量文档。
该FOR
命令可以给出最后修改的日期和时间,但它使用本地化格式,这使得使用通用代码难以解析。更糟糕的是,它忽略了夏令时是否有效。因此,在标准时间和夏令时之间转换任一方向时,不可能准确地确定经过的时间。
WMIC 以不因地区而异的通用格式提供时间戳,以及包含夏令时的时区信息。时间戳的格式在进行字符串比较时按时间顺序排序,这是非常重要且有用的一点。
该getTimestamp.bat
实用程序可用于获取当前时间戳和删除的截止时间戳。如果文件时间戳和当前时间戳在夏令时方面不一致,则需要调整截止时间 + 或 - 一小时。截断的格式与 WMIC 时间戳相匹配,以简化比较。
假设getTimestamp.bat
在您当前的文件夹中,或者更好的是,在您的某个位置PATH
,那么以下应该可以工作。我相信它应该在世界任何地方都可以使用,只要当地的夏令时调整为 1 小时。我不知道是否有任何地区的夏令时不是一个小时。
我通常测试过代码,但我没有测试过夏令时转换日。我可能已经把我的逻辑倒退了。
@echo off
setlocal disableDelayedExpansion
:: Define the folder to delete from.
:: The value must be a path without a file name or file wild cards.
set "folderPath=d:\test"
:: Define the hour offset for the deletion cutoff
set /a hourOffset=-12
for /f "delims=" %%F in ("%folderPath%\") do (
set "driveFilter=%%~dF"
set "pathFilter=%%~pF"
)
for /f "tokens=1-3" %%A in ('getTimestamp -f "{ums} {zzzz} {z}"') do (
set "now=%%A"
set "tz=%%B"
set "z=%%C"
)
call getTimestamp -d %now% -oh %hourOffset% -f {yyyy}{mm}{dd}{hh}{nn}{ss} -r cutoff
call getTimestamp -d %now% -oh %hourOffset%-1 -f {yyyy}{mm}{dd}{hh}{nn}{ss} -r cutoff-1
call getTimestamp -d %now% -oh %hourOffset%+1 -f {yyyy}{mm}{dd}{hh}{nn}{ss} -r cutoff+1
for /f "tokens=1* delims=." %%A in (
'wmic datafile where "Drive='%driveFilter%' and Path='%pathFilter:\=\\%'" get LastModified^,Name'
) do for /f "tokens=2* delims=+- " %%C in ("%%B") do (
if "%%C" neq "%tz:~1%" (
set "fz=%%B"
set "file=%%~fD"
setlocal enableDelayedExpansion
set /a "fz=!fz:~6,1!1!fz:~7,3!%%1000"
if !fz! lss !z! if "%%A" leq "%cutoff-1%" del "!file!"
if !fz! gtr !z! if "%%A" leq "%cutoff+1%" del "!file!"
endlocal
) else (
if "%%A" leq "%cutoff%" del "%%~fD"
)
)
exit /b