<http://www.netikka.net/tsneti/info/tscmd090.htm>
Copyright © 2003-2010 by Prof. Timo Salmi  
Last modified Mon 22-Feb-2010 15:33:18

 
Assorted NT/2000/XP/.. CMD.EXE Script Tricks
From the html version of the tscmd.zip 1cmdfaq.txt file
To the Description and the Index
 

This page is edited from the 1cmdfaq.txt faq-file contained in my tscmd.zip command line interface (CLI) collection. That zipped file has much additional material, including a number of detached .cmd script files. It is recommended that you also get the zipped version as a companion.

Please see "The Description and the Index page" for the conditions of usage and other such information.



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.

References/Comments: (If a Google message link fails try the links within the brackets.)
  Google Groups Apr 14 2005, 10:13 pm [M]