开发者

Batch script to check when the newest file in a directory was created/modified

I'm quite the novice scripter so please forgive me. I need to create a windows batch script that accomplishes the following:

  • checks the root of a specified directory and identifies the most recently modified or created file
  • If the file wasn't modified or created within th开发者_运维问答e past 24 hours (from when the batch file is running) then to execute another specified script. I already have this script handled myself which triggers alerts/emails.

I will be running this via task scheduler. Any help would be greatly appreciated. Thank you!


You should be able to accomplish this with Forefiles


This command lists the files ordered by modification time. The latest one is the last one.

> dir /Od /B

This command runs the previous one and store the last file in variable FILE

> for /F "usebackq" %f in (`dir /Od /B`) do set "FILE=%f"

This command shows file information for a specific file:

> dir /N "%FILE%" | findstr /B "[0-9]"

This command will run the previous command, and parse it. The order of fields (year, month, day...) and the delimiters (/ for date, : for hour in my case) is dependent on your regional settings.

> for /f "usebackq tokens=1-5 eol=\  delims=/:\ " %i in (`dir /N "%FILE%" ^| findstr /B "[0-9]"`) do echo [%i%j%k] [%l%m]

We can store the result in variables:

> for /f "usebackq tokens=1-5 eol=\  delims=/:\ " %i in (`dir /N "%FILE%" ^| findstr /B "[0-9]"`) do set DD=%i&set MM=%j&set YYYY=%k&set HH=%l&set MI=%m

Those commands show the current date and time:

> date /t
> time /t

Those commands run, parse and stores into variables:

> for /F "usebackq tokens=1-3 delims=%DATE_DELIM%" %i in (`date /t`) do set DD=%i&set MM=%j&set YYYY=%k
> for /F "usebackq tokens=1,2 delims=%TIME_DELIM%" %i in (`time /t`) do set HH=%i&set MI=%j

That was the easy part. We now have to do some arithmetics to compare the dates. set /A can do arithmetics, but will interpret "08" as octal. So we have to convert values to decimal by removing the leading '0':

> set /A DD=1%DD%-100&set /A MM=1%MM%-100
> set /A HH=1%HH%-100&set /A MI=1%MI%-100

Here is the final script. I had to use a lot of tricks to do date/time arithmetics, and so "24h" is hard coded.

@echo off
setlocal
set DIR=%~f1
set DATE_DELIM=/
set TIME_DELIM=:
for /F "usebackq" %%f in (`dir /Od /B "%DIR%"`) do set "FILE=%%f"

for /F "usebackq tokens=1-5 eol=\  delims=%DATE_DELIM%%TIME_DELIM%\ " %%i in (`dir /N "%FILE%" ^| findstr /B "[0-9]"`) do set A_DD=%%i&set A_MM=%%j&set A_YYYY=%%k&set A_HH=%%l&set A_MI=%%m
set A_DATE=%A_YYYY%%A_MM%%A_DD%
set /A A_DD=1%A_DD%-100&set /A A_MM=1%A_MM%-100
set /A A_TIME=(1%A_HH%-100)*60+%A_MI%-100

for /F "usebackq tokens=1-3 delims=%DATE_DELIM%\ " %%i in (`date /t`) do set B_DD=%%i&set B_MM=%%j&set B_YYYY=%%k
for /F "usebackq tokens=1,2 delims=%TIME_DELIM%\ " %%i in (`time /t`) do set B_HH=%%i&set B_MI=%%j
set B_DATE=%B_YYYY%%B_MM%%B_DD%
set /A B_DD=1%B_DD%-100&set /A B_MM=1%B_MM%-100
set /A B_TIME=(1%B_HH%-100)*60+%B_MI%-100

echo %A_DATE% %A_TIME% - %A_YYYY% %A_MM% %A_DD%
echo %B_DATE% %B_TIME% - %B_YYYY% %B_MM% %B_DD%

:: Check that the file is newer than 24 hours
:: This will not work at daylight change
:: This is probably full of bugs as I had no time to test all cases

if %A_DATE% GEQ %B_DATE% goto :NewFile

:: Past day
:: Whatever the day, if the time of the day is <, this is old
if %A_HH%%A_MI% LSS %B_HH%%B_MI% goto :OldFile

if not %B_MM%==1 goto :WhateverMonth

if %A_DATE:~1,6% EQU %B_DATE:~1,6% goto :SameMonth
:: Change Month
set /A D=%B_YYYY%*12+%B_MM%-%A_YYYY%*12+%A_MM%
if not %D%==-1 goto :OldFile
:LastMonth
:: Is A the last day of the month => yesterday ?
if %A_DD% EQU 2 goto :February
:: 31 is of course the last day
if %A_DD% EQU 31 goto :NewFile
if %A_DD% LSS 30 goto :OldFile

:: Months of 30 days
if %A_DD%==4 goto :NewFile
if %A_DD%==6 goto :NewFile
if %A_DD%==9 goto :NewFile
if %A_DD%==11 goto :NewFile
:: Day is 30 and month has 31 days
goto :OldFile

:February
set /A D=28+!(%A_YYYY% ^% 4)
if %A_DD%==%D% goto :NewFile
:: We do not have to handle others bissextile case which will happen in about
:: 389 years
goto :OldFile

:WhateverMonth
if %A_YYYY%%A_MM% EQU %B_YYYY%%B_MM% goto :SameMonth
goto :OldFile

:SameMonth
set /A D=100+%B_DD%-%A_DD%
if %D% GTR 101 goto :OldFile
:Yesterday
if %B_DD% GTR 1 goto :ChkTime

:ChkTime

:OldFile
echo %FILE% is old.
goto :End

:NewFile
echo %FILE% is new.
goto :End

:End
endlocal

To run it:

> CheckFile.cmd <directory>

This was just to show you that it is possible. But I would not recommend to put it in production before extensive testing. And it is hard to maintain. So instead of batch I recommend to use JScript in the WSH environment or PowerShell.


ls -t lists the files sorted by modification time. You can grab the first one from its output as the most recently modified.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜