Forfiles command to delete 12 hours old files in .bat file

后端 未结 2 1160
广开言路
广开言路 2020-12-22 00:48

I know the command to delete the files which are olders then days. How to delete 12 hours old files using forfiles command

I am using forfile command in .bat file

相关标签:
2条回答
  • 2020-12-22 01:13

    Ok, I did hard work for you...

    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
    

    Check expected date and time formats in code remarks.

    Note that date and time format are system dependent, so this code must be adapted for different systems.

    0 讨论(0)
  • 2020-12-22 01:19

    It is ridiculous how difficult it is to work with date and time in Windows batch. I suspect PowerShell may be better, but I don't really know.

    I have written a handy hybrid JScript/batch utility that does date and time arithmetic and formatting. It can be used to establish the date and time 12 hours ago, and format it in virtually any format needed. The utility works on any Windows platform from XP onward. It is pure script, so it does not require download or installation of any exe file. getTimestamp.bat is available here. The actual utility is at the bottom of the post, and it includes extensive documentation within the script.

    The FOR command can give the last modified date and time, but it uses localized formatting, which makes it difficult to parse with generic code. To make matters worse, it ignores whether daylight savings was in effect or not. So it becomes impossible to accurately determine the elapsed time on days when transitioning either direction between standard time and daylight savings time.

    WMIC provides the timestamp, complete with time zone information that accounts for daylight savings, in a universal format that does not vary between locales. The timestamp is in a format that sorts chronologically when doing string comparisons, a very important and useful point.

    The getTimestamp.bat utility can be used to get the current timestamp and the cutoff timestamp for deletion. The cutoff needs to be adjusted + or - one hour if the file timestamp and current timestamp do not agree with regard to daylight savings time. The cutoff is formatted to match the WMIC timestamp to make comparisons simple.

    Assuming getTimestamp.bat is either in your current folder, or better yet, somewhere in your PATH, then the following should work. I believe it should work anywhere in the world, as long as the local daylight savings adjustment is 1 hour. I don't know if there are any locales where daylight savings is something other than an hour.

    I've generally tested the code, but I haven't tested the daylight savings transition days. I might have gotten my logic backwards.

    @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
    
    0 讨论(0)
提交回复
热议问题