2

我知道删除旧文件的命令。如何使用 forfiles 命令删除 12 小时前的文件

我在 .bat 文件中使用 forfile 命令

4

2 回答 2

4

好吧,我为你辛苦了……

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

检查代码注释中的预期日期和时间格式。

请注意,日期和时间格式取决于系统,因此该代码必须适用于不同的系统。

于 2013-08-02T10:21:41.393 回答
2

在 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
于 2013-08-03T00:00:57.430 回答