The file renaming task can be done with a batch file with just the following single command line:
@for /F "delims=" %%G in ('dir *.png /A-D-L /B /S 2^>nul ^| %SystemRoot%\System32\findstr.exe /I /R /V "\\Jp-[12][0123456789][0123456789][0123456789][01][0123456789][0123][0123456789]-[^\\]*$"') do @for /F "tokens=1-3 delims=./ " %%H in ("%%~tG") do @ren "%%G" "Jp-%%J%%I%%H-%%~nxG"
ATTENTION: The date/time format of the last modification date/time of a file depends on country/region configured for the used account. So it is necessary to run in a command prompt window for example:
for %I in (%SystemRoot%\notepad.exe) do @echo %~tI
The output date/time can be in format dd.MM.yyyy HH:mm
or MM/dd/yyyy HH:mm
or dd/MM/yyy HH:mm
or another date/time format, see Wikipedia article date format by country. The second for /F
in the command line uses a dot, a slash and a space as delimiters to split up the last modification date/time of a file into three substrings assigned to the loop variables H
, I
and J
. It might be necessary to change the delimiters and/or the order of I
and H
in new name of the file if the date format is not first the day and second the month.
Note: There can be additionally used more wildcard patterns than just *.png
after command dir
in the command line like *.jpg *.jpeg *.png *.tiff
.
The command line results in first starting in background one more cmd.exe
with option /c
and the command line specified within '
as additional arguments. So with Windows installed into C:\Windows
there is executed in the background:
C:\Windows\System32\cmd.exe /c dir *.png /A-D-L /B /S 2>nul | C:\Windows\System32\findstr.exe /I /R /V "\\Jp-[0123456789][0123456789][0123456789][0123456789][0123456789][0123456789][0123456789][0123456789]-[^\\]*$"
The command DIR searches
- in current directory and all subdirectories because of option
/S
- for just files because of option
/A-D-L
(attribute not directory and not link respectively reparse point)
- and outputs them in bare format because of option
/B
which means with just the file name with the file extension with full path because of option /S
.
The output of DIR is redirected with |
to standard input of the next command FINDSTR which searches
- case-insensitive because of option
/I
- with a regular expression because of option
/R
- in each fully qualified file name output by DIR for a string beginning with a backslash escaped with one more backslash to be interpreted as character to find
- followed by
Jp-
and exactly eight digits (some with limited range)
- followed by a hyphen and any other character than a backslash up to end of the line
- and outputs to handle STDOUT of the background command process the inverted result which means all lines not containing the searched string.
In other words FINDSTR is used to filter out all file names starting already with Jp-yyyyMMdd-
to aovid renaming those files once again if the batch file is run multiple times on a directory tree.
[0-9]
would match also ¹²³
which is the reason for using [0123456789]
.
Read the Microsoft documentation about Using command redirection operators for an explanation of |
and 2>nul
. The redirection operators |
and >
must be escaped with caret character ^
on FOR command line to be interpreted as literal characters when Windows command interpreter processes this command line before executing command FOR which executes the embedded command line with using a separate command process started in background.
FOR with option /F
captures everything output to handle STDOUT of the background command process and processes this output line by line after started cmd.exe
closed itself after finishing execution of command DIR and FINSTR.
There are by default ignored all empty lines which does not matter here as there are no empty lines to process from the captured output.
There would be next split up each non-empty line using normal space and horizontal tab character into substrings (tokens) and if the first substring does not start with the default end of line character ;
, only the first substring would be assigned to the specified loop variable G
for further processing. That line splitting behavior is not wanted here as the fully qualified file names can have one or more spaces, but at least cannot start with a semicolon. For that reason the option delims=
is used to define an empty list of string delimiters to prevent the line splitting and getting the entire fully qualified file name assigned to the specified loop variable ´G` one after the other on processing the captured output, i.e. the list of file names with full path.
The second FOR with option /F
is for determining the last modification date/time of the current file and split it up into day, month and year with ignoring hour and minute by using the options tokens=1-3
and delims=./
with first substring being usually day or month assigned to the specified loop variable H
, second substring being usually month or day assigned to next loop variable I
according to the ASCII table and third substring being usually the year assigned to next but one loop variable J
. It should be clear now why the loop variables of command FOR are case-sensitive while nearly everything else of Windows commands is interpreted case-insensitive.
The command REN is executed with the fully qualified file name of current file and the new file name beginning with Jp-
, the determined year, month and day of last modification date of the file, a hyphen and the original file name.
Please note that command REN can fail if the current file is opened by an application which sharing access denying the renaming of the file. The rename can also fail if a file with new file name exists already in the directory.
The character @
left to each command prevents the output of the command before execution. The three @
are not necessary if the batch file contains at top additionally the command line @echo off
.
For renaming the files with using the current date instead of the last modification date of a file can be used the following batch file:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "tokens=1-3 delims=/ " %%G in ('%SystemRoot%\System32\robocopy.exe "%SystemDrive%\|" . /NJH') do set "CurrentDate=%%G%%H%%I" & goto RenameFiles
:RenameFiles
for /F "delims=" %%G in ('dir *.png /A-D /B /S 2^>nul ^| %SystemRoot%\System32\findstr.exe /I /R /V "\\Jp-[12][0123456789][0123456789][0123456789][01][0123456789][0123][0123456789]-[^\\]*$"') do ren "%%G" "Jp-%CurrentDate%-%%~nxG"
endlocal
Please read the chapter Usage of ROBOCOPY to get current date/time in my answer on Time is set incorrectly after midnight for an explanation of getting current date independent on which country/region is configured for the used account.
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.
cmd /?
dir /?
echo /?
endlocal /?
findstr /?
for /?
goto /?
ren /?
robocopy /?
set /?
setlocal /?
See also single line with multiple commands using Windows batch file for a description of the unconditional command operator &
used here to exit the first for /F
loop after processing the first line of output of robocopy
with the current date.