написать пакетный файл для удаления папок по дате и времени - PullRequest
3 голосов
/ 05 марта 2009

Точные дубликаты:

У меня есть папка с именем 'dump' на сервере в сети. Каждый день много временных файлов и папок будут сохраняться в этой папке.

Я хочу удалить эти файлы и подпапки. Условие состоит в том, что я хочу удалить только за час до того, как файлы и папки, т. Е. За один раз до текущего времени, когда мы запускаем пакетный файл.

Это означает, что я хочу сохранить один из наших файлов в этой папке для запуска других действий. как это текущее время.

  1. перейдите в папку и перечислите файлы по времени
  2. получить текущее время
  3. удалить файлы, которые были на 1 час старше текущего времени

Ответы [ 2 ]

1 голос
/ 05 марта 2009

Я думаю, вам лучше использовать PowerShell или WSH (как упоминал Рихан Мейдж) в этом случае. Сравнение данных и времени возможно, но очень хрупко (так как нет способа получить данные / время в пакетном режиме, не зависящие от культуры). Вы могли бы написать что-то вроде этого:

setlocal enableextensions
set Now=%date%
set NowTime=%time:~0,-3%
call :tokenize_date %Now%
call :tokenize_time %NowTime%
echo %YEAR%-%MONTH%-%DAY%T%HOUR%:%MINUTE%:%SECOND%
call :one_hour_before %Now% %NowTime%
echo %RESULT_DATE% %RESULT_TIME%
ping -n 1 -w 1500 ::1>NUL
set Now2=%date%
set NowTime2=%time:~0,-3%
call :date_time_compare %Now% %NowTime% %Now2% %NowTime2%
echo %Now%T%NowTime% compared to %Now2%T%NowTime2%: %RESULT%
endlocal
goto :eof

:tokenize_date
    rem assuming ISO 8601 date format YYYY-MM-DD
    setlocal enableextensions
    set arg=%1
    set YEAR=%arg:~0,4%
    set MONTH=%arg:~5,2%
    set DAY=%arg:~8,2%
    endlocal&set YEAR=%YEAR%&set MONTH=%MONTH%&set DAY=%DAY%
goto :eof

:tokenize_time
    rem assuming ISO-8601 time format HH:MM:SS, 24-hour
    setlocal enableextensions
    set arg=%1
    set HOUR=%arg:~0,2%
    set MINUTE=%arg:~3,2%
    set SECOND=%arg:~6,2%
    endlocal&set HOUR=%HOUR%&set MINUTE=%MINUTE%&set SECOND=%SECOND%
goto :eof

:one_hour_before
    rem gets a date as %1 and a time as %2
    rem returns a date in RESULT_DATE and a time in RESULT_TIME
    setlocal enabledelayedexpansion enableextensions
    set months=31 28 31 30 31 30 31 31 30 31 30 31
    set i=0
    for %%x in (%months%) do (
        set /a i+=1
        set month_length_!i!=%%x
    )
    call :tokenize_date %1
    call :tokenize_time %2
    set /a HOUR-=1
    if %HOUR% LSS 0 (
        set /a DAY-=1
        set /a HOUR+=24
        if %DAY% LSS 0 (
            set /a MONTH-=1
            if %MONTH% LSS 0 (
                set /a YEAR-=1
                set /a MONTH+=12
            )
            set /a DAY+=month_length_!MONTH!
        )
    )
    endlocal&set RESULT_DATE=%YEAR%-%MONTH%-%DAY%&set RESULT_TIME=%HOUR%:%MINUTE%:%SECOND%
goto :eof

:date_time_compare
    rem expects %1 - date 1, %2 - time 1, %3 - date 2, %4 - time 2
    rem returns a value < 0 if datetime1 is earlier than datetime2
    rem                 > 0                 later than
    rem                 = 0                 equal to
    rem the return value is saved in the variable %RETURN%
    setlocal enableextensions
    call :tokenize_date %3
    call :tokenize_time %4
    set YEAR2=%YEAR%
    set MONTH2=%MONTH%
    set DAY2=%DAY%
    set HOUR2=%HOUR%
    set MINUTE2=%MINUTE%
    set SECOND2=%SECOND%
    call :tokenize_date %1
    call :tokenize_time %2
    if %YEAR2% GTR %YEAR% (endlocal&set RESULT=-1&goto :eof) else (
        if %YEAR2% LSS %YEAR% (endlocal&set RESULT=1&goto :eof) else (
            if %MONTH2%%DAY2%%HOUR2%%MINUTE2%%SECOND2% GTR %MONTH%%DAY%%HOUR%%MINUTE%%SECOND% (
                endlocal&set RESULT=-1&goto :eof
            ) else (
                if %MONTH2%%DAY2%%HOUR2%%MINUTE2%%SECOND2%==%MONTH%%DAY%%HOUR%%MINUTE%%SECOND% (
                    endlocal&set RESULT=0&goto :eof
                ) else (
                    endlocal&set RESULT=1&goto :eof
                )
            )
        )
    )
goto :eof

Извините, это стало немного длиннее. Сравнение даты / времени было проверено только частично, но должно работать. Осторожнее со временем, когда оно содержит субсекунды, поскольку они вводят запятую здесь, что нарушает порядок аргументов для вызываемых подпрограмм (отсюда %time:~0,-3%, чтобы избежать этого).

После этого вы можете использовать расширение %~tI, чтобы получить дату и время, сравнить их с текущим минус один час и удалить, если применимо.

Примечание 1: Я предполагаю, что форматы даты и времени ISO 8601 используют 24 часа, что я и использую здесь. Для нестандартных форматов даты вам придется немного изменить подпрограммы (но 12-часовое время, вероятно, будет проблемой).

Примечание 2: в настоящее время код не заботится о високосных годах. Думаю, будет еще 5 или 6 строк кода в :one_hour_before.

0 голосов
/ 05 марта 2009

Единственный способ, которым я знаю, что я знаю, что то, что вы пытаетесь сделать, может быть возможным, - это использование команды for и параметра расширения ~ t.

for %r in (*.*) DO echo %r "created on" %~tr

Что производит:

C:\>echo BOOTSECT.BAK "created on" 2009/02/17 11:59 PM
BOOTSECT.BAK "created on" 2009/02/17 11:59 PM

C:\>echo config.sys "created on" 2006/09/18 11:43 PM
config.sys "created on" 2006/09/18 11:43 PM

Я думаю, что более вероятный сценарий будет включать использование скриптового хоста windows или powershell, но вы не упомянули, что это варианты для вас, поэтому я предполагаю, что есть веская причина, чтобы не использовать эти технологии .

...