Reputation:
I'm quite the novice scripter so please forgive me. I need to create a windows batch script that accomplishes the following:
I will be running this via task scheduler. Any help would be greatly appreciated. Thank you!
Upvotes: 1
Views: 6931
Reputation: 8696
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.
Upvotes: 1
Reputation: 322
ls -t
lists the files sorted by modification time. You can grab the first one from its output as the most recently modified.
Upvotes: 0