90} How do I get the most recent file within a directory structure?
Pinpointing the most recent file in a folder is not very difficult
@echo off & setlocal enableextensions
set myfolder_=C:\WhateverTheFolder
for /f "delims=" %%f in (
'dir /o:d /a:-d /b "%myfolder_%\
*.*"') do (
set latest_=%myfolder_%\%%~
nxf)
if defined latest_ (
echo rem DoWhatever "%latest_%"
) else (
echo No designated files found in "%myfolder_%")
endlocal & goto :EOF
The output could be e.g.
C:\_D\TEST>cmdfaq
rem DoWhatever "C:\WhateverTheFolder\MyRecent.txt"
Depending on your task, you might have something else than *.* like
*.LOG
Getting
the most recent file in an entire directory structure is
a bit more complicated:
@echo off & setlocal enableextensions
enabledelayedexpansion
::
:: Define the root folder of the search
set rootFolder=C:\WhateverTheFolder
::
:: Ensure that the auxiliary directory file does not already exist
for /f "tokens=*" %%f in ("%temp%") do set temp_=%%~
sf
if exist %temp_%temp.dir del %temp_%temp.dir
::
:: Make a directory with the date/time as YYYYMMDD HH:MM
:: Assumes a DD.MM.YYYY date and a 24-hour time, i.e. no am/pm
for /f "tokens=*" %%f in (
'dir "%rootFolder%\
*.*" /s /b /-c /a:-d-s-h /o:d') do (
set fdate_=%%~tf
set fRevisedDate_=!fdate_:~6,4!!fdate_:~3,2!!fdate_:~0,2!
set ftime_=!fdate_:~11,2!!fdate_:~14,2!
echo !fRevisedDate_! !ftime_! "%%f">>%temp_%temp.dir)
::
:: Was anything found
if not exist %temp_%temp.dir (
echo No designated files found in "%rootFolder%" or below
goto :EOF)
::
:: Sort the directory listing by the date/time stamp
sort %temp_%temp.dir /o %temp_%tempsort.dir
::
:: Get the last line of the sorted directory listing
for /f "delims=" %%r in ('type %temp_%tempsort.dir') do (
set LastLine_=%%r)
echo.%LastLine_%
::
:: Clean up
for %%f in (temp.dir tempsort.dir) do (
if exist %temp_%%%f del %temp_%%%f)
endlocal & goto :EOF
The output could be e.g.
C:\_D\TEST>cmdfaq
20050414 1742 "C:\_F\VPP\DAT\TSKP6504.WKT"
If you want only the filename, substitute
echo.%LastLine_:~14%
There is a catch, however. Since
enabledelayedexpansion
has been applied, the file names with exclamation marks would miss the
exclamation mark
! To circumvent this
dilemma, use a subroutine call instead.
@echo off & setlocal enableextensions disabledelayedexpansion
::
:: Define the root folder of the search
set rootFolder=C:\WhateverTheFolder
::
:: Ensure that the auxiliary directory file does not already exist
for /f "tokens=*" %%f in ("%temp%") do set temp_=%%~sf
if exist %temp_%temp.dir del %temp_%temp.dir
::
:: Make a directory with the date/time as YYYYMMDD HH:MM
:: Assumes a DD.MM.YYYY date and a 24-hour time, i.e. no am/pm
for /f "tokens=*" %%f in (
'dir "%rootFolder%\*.*" /s /b /-c /a:-d-s-h /o:d') do (
call :PutInfo "%%~ff")
::
:: Was anything found
if not exist %temp_%temp.dir (
echo No designated files found in "%rootFolder%" or below
goto :EOF)
::
:: Sort the directory listing by the date/time stamp
sort %temp_%temp.dir /o %temp_%tempsort.dir
::
:: Get the last line of the sorted directory listing
for /f "delims=" %%r in ('type %temp_%tempsort.dir') do (
set LastLine_=%%r)
echo.%LastLine_%
::
:: Clean up
for %%f in (temp.dir tempsort.dir) do (
if exist %temp_%%%f del %temp_%%%f)
endlocal & goto :EOF
::
:: =======================================================
:PutInfo
setlocal enableextensions disabledelayedexpansion
set fdate_=%~t1
set fRevisedDate_=%fdate_:~6,4%%fdate_:~3,2%%fdate_:~0,2%
set ftime_=%fdate_:~11,2%%fdate_:~14,2%
>>%temp_%temp.dir echo %fRevisedDate_% %ftime_% "%~1"
endlocal & goto :EOF
How about getting the last five most recent files instead of the
latest only? One option is
@echo off & setlocal enableextensions
disabledelayedexpansion
::
:: Define the root folder of the search
set rootFolder=C:\WhateverTheFolder
::
:: Ensure that the auxiliary directory file does not already exist
for /f "tokens=*" %%f in ("%temp%") do set temp_=%%~sf
if exist %temp_%temp.dir del %temp_%temp.dir
::
:: Make a directory with the date/time as YYYYMMDD HH:MM
:: Assumes a DD.MM.YYYY date and a 24-hour time, i.e. no am/pm
for /f "tokens=*" %%f in (
'dir "%rootFolder%\
*.*" /s /b /-c /a:-d-s-h /o:d') do (
call :PutInfo "%%~ff")
::
:: Was anything found
if not exist %temp_%temp.dir (
echo No designated files found in "%rootFolder%" or below
goto :EOF)
::
:: Sort the directory listing by the date/time stamp
sort /r %temp_%temp.dir /o %temp_%tempsort.dir
::
:: Get the first five lines of the sorted directory listing
set skip=
findstr "'%skip%VBS" "%~f0" > "%temp%\tmp$$$.vbs"
cscript //nologo "%temp%\tmp$$$.vbs" < %temp_%tempsort.dir
::
:: Clean up
for %%f in (temp.dir tempsort.dir) do (
if exist %temp_%%%f del %temp_%%%f)
if exist "%temp%\tmp$$$.vbs" del "%temp%\tmp$$$.vbs"
endlocal & goto :EOF
::
:: =======================================================
:PutInfo
setlocal enableextensions disabledelayedexpansion
set fdate_=%~t1
set fRevisedDate_=%fdate_:~6,4%%fdate_:~3,2%%fdate_:~0,2%
set ftime_=%fdate_:~11,2%%fdate_:~14,2%
>>%temp_%temp.dir echo %fRevisedDate_% %ftime_% "%~1"
endlocal & goto :EOF
'
'...............................................................
'A Visual Basic "head -5" Script to display the first five lines
i = 0 'VBS
Do While Not WScript.StdIn.AtEndOfStream 'VBS
i = i + 1 'VBS
If i >
5 Then Exit Do 'VBS
str = WScript.StdIn.ReadLine 'VBS
WScript.StdOut.WriteLine str 'VBS
Loop 'VBS
The output could be e.g.
C:\_D\TEST>cmdfaq
20050414 2237 "C:\_D\BAS\TEST 2.CMD"
20050415 1205 "C:\_D\OPETUS\JATKO\JATKOP.XLS"
20050415 2002 "C:\_D\WORD\TIMOSUOM.DIC"
20050415 2120 "C:\_D\OPETUS\JOTT\TUL\JOTTTUL.MAI"
20050415 2351 "C:\_D\TEST\CMDFAQ.CMD"
Another approach to the task at hand would be to customize
RECENT.CMD CMD shell for RECENT.VBS
RECENT.VBS Search folders for recent files
They are included as separate files in the CMD FAQ package. The
advantage of the VBS solution is that the date/time stamps will
cover also seconds.