6

The batch command below will get me the newest file in a folder, however I'm only looking for files with a specific extension. Can anyone explain how to specify the extension (i.e. .jpg)

FOR /F "delims=|" %%I IN ('DIR "C:\Jenkins\Releases\C9metro" /B /O:D') DO SET NewestFile=%%I
NealR
  • 10,189
  • 61
  • 159
  • 299

2 Answers2

9

I suggest to use the following lines:

FOR /F "eol=| delims=" %%I IN ('DIR "C:\Jenkins\Releases\C9metro\*.jpg" /A-D /B /O-D /TW 2^>nul') DO (
    SET "NewestFile=%%I"
    GOTO FoundFile
)
ECHO No *.jpg file found!
GOTO :EOF

:FoundFile
ECHO Newest *.jpg file is: "%NewestFile%"

The FOR loop can be also optimized to a single command line:

FOR /F "eol=| delims=" %%I IN ('DIR "C:\Jenkins\Releases\C9metro\*.jpg" /A-D /B /O-D /TW 2^>nul') DO SET "NewestFile=%%I" & GOTO FoundFile
ECHO No *.jpg file found!
GOTO :EOF

:FoundFile
ECHO Newest *.jpg file is: "%NewestFile%"

FOR starts in background one more cmd.exe with option /c and the command line within ' appended as additional arguments. There is executed in this case in background with Windows installed into C:\Windows:

C:\Windows\System32\cmd.exe /c DIR "C:\Jenkins\Releases\C9metro\*.jpg" /A-D /B /O-D /TW 2>nul

The internal command DIR searches now for file system entries in the specified directory matching the wildcard pattern *.jpg with following additional restrictions.

The parameter /A-D makes sure ignoring subdirectories which unusually end by chance also with the string .jpg.

The parameter /B turns on bare output format. In this case are output just the file names without path by command DIR never enclosed in " even on containing a space or one of these characters &()[]{}^=;!'+,`~ which require the file name string to be enclosed in " on further processing it by cmd.exe on other command lines.

The parameter /O-D results in getting output by DIR the found file names listed by date in reverse order from newest to oldest. In other words the file name of the newest file is output first and the file name of the oldest file is output last.

And parameter /TW makes sure the last modification time (write access) is used for ordering the found file names of the JPEG files in date order and not the creation or the last access time.

There could be no file name matching the wildcard pattern *.jpg in long or short 8.3 name in which case DIR outputs an error message to standard error stream STDERR of the background command process. cmd.exe processing the batch file would redirect that error output to its own standard error stream. That would result in displaying the error message in the console window not really useful for a user of the batch file. The usage of 2>nul instructs cmd.exe started in background to redirect the error message to device NUL to suppress it.

Read the Microsoft documentation about Using command redirection operators for an explanation of 2>nul. The redirection operator > must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir command line with using a separate command process started in background.

FOR respectively cmd.exe processing the batch file captures all output written to standard output stream of in background started cmd.exe and processes it line by line after started cmd.exe closed itself after finishing executing the command DIR.

FOR on using option /F ignores always empty lines which is no problem here as DIR with the used options does not output empty lines.

FOR would next split up the lines into substrings using horizontal tab and normal space as string delimiters, would look next if first tab/space separated string begins with a semicolon in which case it would also ignore the entire line for further processing, and would otherwise assign just the first tab/space separated string to the specified loop variable I before running the commands in body of FOR.

The default line splitting behavior is not wanted as JPEG file names can contain one or more spaces. The usage of the option delims= defines an empty list of delimiters which turns off the line splitting behavior.

It is very unusual but nevertheless possible that a JPEG file name begins with ; (semicolon). Such a file name should not be ignored by FOR. The option eol=| defines a vertical bar as end of line character which no file name can contain ever. Microsoft lists the characters not allowed in a file name on Windows file systems in the documentation about Naming Files, Paths, and Namespaces.

So, the first file name output by DIR being from the newest file is assigned completely to the loop variable I and executed is the command SET to assign this string to the environment variable NewestFile.

The loop is exited on first found file matching the wildcard pattern *.jpg is assigned to the environment variable. That makes this method faster than letting DIR output the file names from oldest to first and assigning all file names one after the other to the variable NewestFile up to last found file which would be the newest file.

There is an error message output on DIR could not find any file and so FOR could not assign any file name string to the loop variable I and run once the commands SET and GOTO. Then the batch file processing is exited in this case as described in detail by Where does GOTO :EOF return to?

To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.

  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • set /?
  • setlocal /?

See also:

Mofi
  • 46,139
  • 17
  • 80
  • 143
2

It's early... figured this one out:

'DIR "C:\Jenkins\Releases\C9metro\*.jpg"
NealR
  • 10,189
  • 61
  • 159
  • 299
  • The execution of this command line in a Windows Command Prompt window or in a batch file results in the error message `''DIR' is not recognized as an internal or external command, operable program or batch file.` because of `'` at beginning. But this command line with `'` removed results only in listing all files with file extension `.jpg` in the directory `C:\Jenkins\Releases\C9metro` by __DIR__ which does not answer the question at all. – Mofi Oct 30 '22 at 07:48