Rename a file or files.
REN [drive:][path]SourceMask TargetMask
RENAME is a synonym for REN
You cannot specify a different drive or path for TargetMask - use the MOVE command instead.
Both the SourceMask and TargetMask can contain * and/or ? wildcards. The behavior of the wildcards changes slightly between source and target masks.
By default REN with a wildcard will only rename the files in a single folder, to recurse down into sub folders use a FOR /R command, after first changing to the top level directory.
e.g. A batch file to rename all .LOG files to .TXT in the 'demo' folder and all sub-folders:
CD C:\demo\
For /R %%G in (*.LOG) do Echo REN "%%G" "%~nG.TXT"
Remove the echo to run this for real
The sourceMask works as a filter to determine which files are renamed. The wildcards work here the same as with any other command that filters file names.
? Matches any 0 or 1 character except . This wildcard is greedy - it always consumes the next character if it is not a . However it will match nothing without failure if at name end or if the next character is a .
* Matches any 0 or more characters including . (with one exception below). This wildcard is not greedy. It will match as little or as much as is needed to enable subsequent characters to match.
All non-wildcard characters must match themselves, with a few special case exceptions.
. Matches itself or it can match the end of name (nothing) if no more characters remain. (Note - a valid Windows name cannot end with .)
{space} Matches itself or it can match the end of name (nothing) if no more characters remain. (Note - a valid Windows name cannot end with {space})
*. at the end, Matches any 0 or more characters except . The terminating . can actually be any combination of . and {space} as long as the very last character in the mask is . this is the one and only exception where * does not simply match any set of characters.
The above rules are not that complex. But there is one more very important rule that makes the situation confusing: The SourceMask is compared against both the long name and the short 8.3 name (if it exists). This last rule can make interpretation of the results very tricky, because it is not always obvious when the mask is matching via the short name.
It is possible to use RegEdit to disable the generation of short 8.3 names on NTFS volumes, at which point interpretation of file mask results is much more straight forward. Any short names that were generated before disabling short names will remain.
The TargetMask specifies the new name. It is always applied to the full long name; The TargetMask is never applied to the short 8.3 name, even if the SourceMask matched the short 8.3 name.
The presence or absence of wildcards in the SourceMask has no impact on how wildcards are processed in the TargetMask.
In the following discussion c represents any character that is not *, ?, or .
The TargetMask is processed against the source name strictly from left to right with no back-tracking.
c Advances the position within the source name as long as the next character is not . and appends c to the target name. (Replaces the character that was in source with c, but never replaces .)
? Matches the next character from the source long name and appends it to the target name as long as the next character is not . If the next character is . or if at the end of the source name then no character is added to the result and the current position within the source name is unchanged.
* At end of sourceMask - Appends all remaining characters from source to the target. If already at the end of source, then does nothing.
*c Matches all source characters from current position through the last occurance of c (case sensitive greedy match) and appends the matched set of characters to the target name. If c is not found, then all remaining characters from source are appended, followed by c This is the only situation I am aware of where Windows file pattern matching is case sensitive.
*. Matches all source characters from current position through the last occurance of . (greedy match) and appends the matched set of characters to the target name. If . is not found, then all remaining characters from source are appended, followed by .
*? Appends all remaining characters from source to the target. Any additional characters after the *? in sourceMask will be appended to target. If already at end of source then does nothing.
. without * in front - Advances the position in source through the first occurance of . without copying any characters, and appends . to the target name. If . is not found in the source, then advances to the end of source and appends . to the target name.
After the TargetMask has been exhausted, any trailing . and {space} are trimmed off the end of the resulting target name because Windows file names cannot end with . or {space}
It appears these same rules also work for the target name of the COPY commmand.
When 8.3 filenames exist then the SourceMask will first look for a match against the long file name, and then against the short file name. If the result of the first rename operation still matches the SourceMask then the same file can be renamed twice. For example:
copy nul 123456789.123 dir /x ren *1* 2*3.?x dir /xExpected result = 223456789.123.x
Actual result = 223456789.123.xxIf 8.3 name generation is enabled, the SourceMask matches the original long name, the initial rename generates a short name that still matches SourceMask and sorts later in the alphabet, then this bug might be triggered.
If 8.3 name generation is disabled then RENAME always gives the expected result.
If the File(s) were successfully renamed %ERRORLEVEL% = 0
If the File was not found, could not be renamed or bad parameters %ERRORLEVEL% = 1
Examples
Rename Monday.txt as Tuesday.txt
C:\> REN Monday.txt Tuesday.txt
Substitute a character in the 1st and 3rd positions prior to any extension (adds a 2nd or 3rd character if it doesn't exist yet)
ren * A?Z* 1 -> AZ 12 -> A2Z 1.txt -> AZ.txt 12.txt -> A2Z.txt 123 -> A2Z 123.txt -> A2Z.txt 1234 -> A2Z4 1234.txt -> A2Z4.txt
Change the (final) extension of every file
ren * *.txt a -> a.txt b.dat -> b.txt c.x.y -> c.x.txt
Append an extension to every file
ren * *?.bak a -> a.bak b.dat -> b.dat.bak c.x.y -> c.x.y.bak
Remove any extra extension after the initial extension. Note that adequate ? must be used to preserve the full existing name and initial extension.
ren * ?????.????? a -> a a.b -> a.b a.b.c -> a.b part1.part2.part3 -> part1.part2 123456.123456.123456 -> 12345.12345 (note truncated name and extension because not enough `?` were used)
Same as above, but filter out files with initial name and/or extension longer than 5 chars so that they are not truncated. (Obviously could add an additional ? on either end of targetMask to preserve names and extensions up to 6 chars long.)
ren ?????.?????.* ?????.????? a -> a a.b -> a.b a.b.c -> a.b part1.part2.part3 -> part1.part2 123456.123456.123456 (Not renamed because it doesn't match sourceMask)
Change characters after last _ in name and attempt to preserve extension. (Doesn't work properly if _ appears in extension.)
ren *_* *_NEW.* abcd_12345.txt -> abcd_NEW.txt abc_newt_1.dat -> abc_newt_NEW.txt abcdef.jpg (Not renamed because it doesn't match sourceMask) abcd_123.a_b -> abcd_123.a_NEW (not desired, but no simple RENAME form will work in this case)
Any name can be broken up into components that are delimited by . characters can only be appended to or deleted from the end of each component. Characters cannot be deleted from or added to the beginning or middle of a component while preserving the remainder with wildcards. Substitutions are allowed anywhere.
ren ??????.??????.?????? ?x.????999.*rForTheCourse part1.part2 -> px.part999.rForTheCourse part1.part2.part3 -> px.part999.parForTheCourse part1.part2.part3.part4 (Not renamed because it doesn't match sourceMask) a.b.c -> ax.b999.crForTheCourse a.b.CarPart3BEER -> ax.b999.CarParForTheCourse
A sourceMask with at least 8 ? for the name and at least 3 ? for the extension will match all files because it will always match the short 8.3 name.
ren ????????.??? ?x.????999.*rForTheCourse part1.part2.part3.part4 -> px.part999.part3.parForTheCourse
Credits:
Dave Benham - List of How does the Windows RENAME command interpret wildcards? from SuperUser Dec 2012
REN is an internal command.
“We may dig in our heels and dare life never to change, but, all the same, it changes under our feet like sand under the feet of a sea gazer as the tide runs out. Life is forever undermining us. Life is forever washing away our castles, reminding us that they were, after all, only sand and sea water” - Erica Jong (Parachutes and Kisses)
Related:
MOVE - Move a file from one folder to another.
Stamp.cmd - Batch file to rename a file to include the current date and time.
Powershell: Rename-Item - Change the name of an existing item (ren/rni).
Equivalent bash command (Linux): mv - Move or rename files or directories.