问题
I am trying to get the Date and Time (on a variable) of the most recently modified file in the Logs folder but I always get an error ('was unexpected at this time.')
I am using the following code:
@echo off
SETLOCAL
for /f %%G in ('dir .\Logs /b/a-d/o-d/t:w') do (
if not defined NewestFileTime (
set NewestFileTime=%%~tG
) else (
if %NewestFileTime% GTR %%~tG set NewestFileTime=%%~tG
)
)
if not defined NewestFileTime (
echo There is no file in current directory.
goto :exit
)
echo Last file modification time is: %NewestFileTime%
:exit
endlocal
echo.
echo Press CTRL+C to exit
pause
回答1:
You have a complex of overlapping bugs in your script:
- You need to have delayed expansion enabled, due to the code blocks.
- You used the wrong operator in your comparison.
- You must quote the strings in the comparison.
One thing you should always be aware of, when comparing strings, particularly those that represent numbers, is the comparison is based on the code points of your configured language. So "2019-1-1" < "2019-01-01"
due to the the different lengths of the strings. But it is okay to compare date/time strings that use the same format, if and only if they adhere to the full YYYY-MM-DD
and hh:mm am|pm
formats.
Here's your fixed up code:
@echo off
setlocal EnableExtensions EnableDelayedExpansion
for /f %%G in ('dir .\Logs /b/a-d/o-d/t:w') do (
if not defined NewestFileTime (
set NewestFileTime=%%~tG
) else (
if "!NewestFileTime!" LSS "%%~tG" set NewestFileTime=%%~tG
)
)
if not defined NewestFileTime (
echo There is no file in current directory.
goto :exit
)
echo Last file modification time is: %NewestFileTime%
:exit
endlocal
echo.
echo Press CTRL+C to exit
pause
Tested against this directory on my system:
Directory of D:\TMP\test\Logs
2020-02-04 11:37 AM <DIR> .
2020-02-04 11:37 AM <DIR> ..
2020-01-16 02:07 AM 135 fqpnTest.cmd
2020-02-04 11:32 AM 578 test.cmd
2020-02-04 11:37 AM 15 test.txt
3 File(s) 728 bytes
Results are:
> test
Last file modification time is: 2020-02-04 11:40 AM
Press CTRL+C to exit
Press any key to continue . . .
The apparent time discrepancy is caused by the fact that my creation times aren't equal to my last update times.
回答2:
For a single
file
and also get date/time of the first outputs of the commands below in the loopfor
:
dir .\*.log /b /a:-d /o-d /t:w
%__APPDIR__%wbem\wmic.exe datafile where name="G:\\some_folder\\file_.ext" get "LastModified"
@echo off && setlocal enabledelayedexpansion
cd /d "%~dp0" & cls & echo/ && title <nul && title ...\%~nx0
for /f "tokens=* delims= " %%i in ('dir .\*.log /b /a:-d /o-d /t:w')do set "_F=%%~fi" && for /f ^tokens^=^1^ ^delims^=^+^. %%d in ('
%__APPDIR__%wbem\wmic.exe datafile where name^="!_F:\=\\!" get "LastModified"^|%__APPDIR__%findstr.exe [0-9]')do set "_d=%%~d" && (
call set "_d=!_d:~0,14!" && call set "_ft=%%~nxi !_d:~0,4!/!_d:~4,2!/!_d:~6,2! !_d:~8,2!:!_d:~10,2!:!_d:~12,2!" && set "_nft=%%~xni"
goto :next )
:next
echo/ && for /f "tokens=1-3*delims= " %%i in ('echo[!_ft!')do set "_f=%%~i" && set "_df=%%~j" && set "_~t=%%~ti" && set "_t=%%~k"
echo/ File Name: !_f! && echo/ File Date: !_df! & echo/ File Time: !_~t! & echo/ Date and Time for the variable %%%%~ti is: !_~t!
call echo/ Name !_f! Date !_df! Time !_t! & echo/ WMIC Last Modified is: !_d! & %__APPDIR__%timeout.exe -1 & endlocal & goto :EOF
- Same code in conventional formatting:
@echo off && setlocal enabledelayedexpansion
cd /d "%~dp0"
cls
echo/
title <nul
title ...\%~nx0
for /f "tokens=* delims= " %%i in ('dir .\*.log /b /a:-d /o-d /t:w')do (
set "_F=%%~fi"
for /f "tokens=1 delims=+." %%d in (
'%__APPDIR__%wbem\wmic.exe datafile where name^="!_F:\=\\!" get "LastModified"^|%__APPDIR__%findstr.exe [0-9]'
) do (
set "_d=%%~d" && (
call set "_d=!_d:~0,14!"
call set "_ft=%%~nxi !_d:~0,4!/!_d:~4,2!/!_d:~6,2! !_d:~8,2!:!_d:~10,2!:!_d:~12,2!"
set "_nft=%%~xni"
goto :next
)
)
)
:next
echo/
for /f "tokens=1-3*delims= " %%i in ('echo[!_ft!')do (
set "_f=%%~i"
set "_df=%%~j"
set "_~t=%%~ti"
set "_t=%%~k"
)
echo/ File Name: !_f!
echo/ File Date: !_df!
echo/ File Time: !_~t!
echo/ Date and Time for the variable %%%%~ti is: !_~t!
call echo/ Name !_f! Date !_df! Time !_t!
echo/ WMIC Last Modified is: !_d!
%__APPDIR__%timeout.exe -1
endlocal
goto :EOF
- Outputs file bat/cmd:
File Name: Q60062965.LOG
File Date: 2020/02/12
File Time: 2020-02-12 12:56 AM
Date and Time for the variable %%~ti is: 2020-02-12 12:56 AM
Name Q60062965.LOG Date 2020/02/12 Time 00:56:14
WMIC Last Modified is: 20200212005614
For multiple files:
- To get the date/time the file was last modified, try using
wmic
instead %%~ti in afor
variable looping:
%__APPDIR__%wbem\wmic.exe datafile where name="G:\\some_folder\\file_.ext" get "LastModified"
- To compare dates and get the latest modified file, I am using a date format
yyyyMMDDHHmmss
.
So, with this layout, I compose a number where the most recent value is always known with the highest numerical value.
To compare the value and get the largest between two dates/numbers with 14 digits, why not help a little with vbs
- For use/test, just edit:
cd /d "%~dp0"
toc:\folder\logs
@echo off && setlocal enabledelayedexpansion
cd /d "%~dp0" & cls & echo/
title <nul && title ...\%~nx0
set "_yep=%temp%\_yep_tmp.vbs"
set "_vbs=%__APPDIR__%cscript.exe"
set "_fstr=%__APPDIR__%findstr.exe"
set "_dir=dir .\*.log /b /a:-d /o-d /t:w"
set "_wmic=%__APPDIR__%wbem\wmic.exe datafile where name"
>"!_yep!" echo/if int(wsh.Arguments(0^)^)^>=int(wsh.Arguments(1^)^)then wsh.echo "yep"
for /f ^tokens^=^* %%i in ('call !_dir!')do (set "_F=%%~fi" && for /f tokens^=^1^ ^delims^=^+. %%d in (
'!_wmic!^="!_F:\=\\!" get "LastModified" ^|call !_fstr! [0-9]')do (set "_d=%%~d" && if "!_NFT!" == "" (
set "_NFT=!_d:~0,14!" && set "_ft=%%~nxi !_d:~0,4!/!_d:~4,2!/!_d:~6,2! !_d:~8,2!:!_d:~10,2!:!_d:~12,2!"
) else (call !_vbs! "!yep!" !_d:~0,14! !_NFT!|call !_fstr! yep >nul && call set "_NFT=!_d:~0,14!") && (
call set "_ft=%%~nxi !_d:~0,4!/!_d:~4,2!/!_d:~6,2! !_d:~8,2!:!_d:~10,2!:!_d:~14,4!"))& echo/ %%~i !_d!)
echo/ & for /f "tokens=1-3" %%i in ('echo[!_ft!')do (set "_f=%%i" && set "_df=%%~j" && set "_~t=%%~ti"
set "_t=%%~k" && call echo/ File Name: !_f! && call echo/ File Date: !_df! && echo/ File Time: %%~ti )
echo/ & echo/ Date and Time for the variable %%%%~ti is !_~t! && echo/ WMIC.exe command outputs !_NFT!
echo/ Name !_f! Date !_df! Time !_t! && echo/ WMIC Last Modified: !_NFT! && %__APPDIR__%timeout.exe -1
del /q /f "!_yep!" 2>nul >nul & endlocal && goto :EOF
- Outputs file bat/cmd:
Q60062965.log 20200211231602
Q26635801.log 20190801440758
Q18326477.log 20191821232201
File Name: Q60062965.log
File Date: 2020/02/11
File Time: 2020-02-11 11:16 PM
Date and Time for the variable %%~ti is 2020-02-11 11:16 PM
WMIC.exe command outputs 20200211231602
Name Q60062965.log Date 2020/02/11 Time 23:16:02
WMIC Last Modified: 20200211231602
- The vbs code for check date/time
>=
with no escaping::
if int(wsh.Arguments(0))>=int(wsh.Arguments(1))then wsh.echo "yep"
- The command line to run/execute vbs file
%temp%\_yep_tmp.vbs
:
%__APPDIR__%cscript.exe "%temp%\_yep_tmp.vbs" 20200211180712 20200211174953
- Outputs file vbs:
yep
- Same code in conventional formatting
@echo off && setlocal enabledelayedexpansion
cd /d "%~dp0" & cls & echo/
title <nul && title ...\%~nx0
>"%temp%\_yep_tmp.vbs" echo/if int(wsh.Arguments(0^)^)^>=int(wsh.Arguments(1^)^)then wsh.echo "yep"
for /f "tokens=*" %%i in ('dir .\*.log /b /a:-d /o-d /t:w')do (
set "_F=%%~fi"
for /f "tokens=1 delims=+." %%d in (
'%__APPDIR__%wbem\wmic.exe datafile where name^="!_F:\=\\!" get "LastModified" ^|%__APPDIR__%findstr.exe [0-9]')do (
set "_d=%%~d"
if "!_NFT!" == "" (
set "_NFT=!_d:~0,14!"
set "_ft=%%~nxi !_d:~0,4!/!_d:~4,2!/!_d:~6,2! !_d:~8,2!:!_d:~10,2!:!_d:~12,2!"
) else (
%__APPDIR__%cscript.exe "%temp%\_yep_tmp.vbs" !_d:~0,14! !_NFT!|%__APPDIR__%findstr.exe! yep >nul
call set "_NFT=!_d:~0,14!"
) && (
call set "_ft=%%~nxi !_d:~0,4!/!_d:~4,2!/!_d:~6,2! !_d:~8,2!:!_d:~10,2!:!_d:~14,4!"
)
)
echo/ %%~i !_d!
)
echo/
for /f "tokens=1-3" %%i in ('echo[!_ft!')do (
set "_f=%%i"
set "_df=%%~j"
set "_~t=%%~ti"
set "_t=%%~k"
call echo/ File Name: !_f!
call echo/ File Date: !_df!
echo/ File Time: %%~ti
)
echo/
echo/ Date and Time for the variable %%%%~ti is !_~t!
echo/ WMIC.exe command outputs !_NFT!
echo/ Name !_f! Date !_df! Time !_t!
echo/ WMIC Last Modified: !_NFT!
del /q /f "!_yep!" 2>nul >nul
%__APPDIR__%timeout.exe -1
endlocal
goto :EOF
来源:https://stackoverflow.com/questions/60062965/i-am-trying-to-get-the-date-and-time-on-a-variable-of-the-most-recently-modifi