Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

In a directory with multiple sub directories, I need to change file names that have the _ character to a another character: ., for example:

ABC12345_DEF --> ABC12345.DEF

I need to do this recursively through a directory tree.
The last three characters of the file name are not always the same.

Using rename wildcards on either side of the _ or . doesn't work (plus I need to do this through several directories).

share|improve this question
Operating system? – Daniel Beck Feb 8 '11 at 5:37
possible duplicate… – Patrick Feb 8 '11 at 5:41
Windows XP. The last three characters are not the same on the files – PilotMom Feb 8 '11 at 5:41
up vote 0 down vote accepted

The following should work. I used move instead of ren due to the peculiarities of ren in handling filenames in quotes.

for /f "tokens=1,2 delims=_" %i in ( 'dir /s/b *_*.' ) do @( move "%i_%j" "%i.%j" )

You can remove the @ if you'd like to visually track the progress of the command.

share|improve this answer
You're remarkable !!! THANK YOU!!!! – PilotMom Feb 8 '11 at 6:01
Can I put this as written in a BAT file for future use? or do I need to add something to make it work ... I really appreciate your help! – PilotMom Feb 8 '11 at 6:06
To make it work in a batch file, you need to change all of the variables that use a single percent sign to a double percent sign; i.e. change all instances of %i to %%i and %j to %%j. – Asterisk Feb 8 '11 at 6:39
Thank you! You save me from carpul tunnel syndrome! – PilotMom Feb 8 '11 at 6:41
Since dir /s/b returns the complete path and filename, ren would fail because ren doesn't like the second argument %i.%j to contain a path. Move likes it just fine. – Kevin Fegan Nov 18 '12 at 9:19

This batch file should do it for you.

Copy the batch file below into a text file and save it as xrename.cmd (or "whatever you want.cmd").

If you just run the file like this:

It will look in the current folder and all subfolders, and rename all files like: ABC12345_DEF to ABC12345.DEF (anything like "text_moretext" to "text.moretext").

You can also provide values for "search-string", "replace-string", and "search-pattern" on the command line.

To show instructions, run it like this:
xrename.cmd /help

Note: I made the batch file to only display the files that will be renamed, no renaming will actually take place. You can run the batch file and see what will happen without actually renaming anything. Once you have run it and are confident the correct files will be properly renamed, you can delete the line as described below to make renaming active, then run the batch file again.

You might have to modify the value of "search-pattern" to display the files you want.

At the labels ":default1" and ":default2", you can edit the values for "match-string" "search-pattern" and "replace-string" to suit your needs.

This batch file has some error checking and it won't fail if the "match-string" is found in the names of any of the folders or subfolders.

@echo off

if "%~1%~2%~3."=="." goto :default1
if /i "%~1."=="/help." goto :syntax
if "%~1."=="." goto :syntax

rem %2 can be empty to use "*matchstring*" as the "search-pattern"
rem %3 can be empty to make replacement with empty string (delete matchstring).

set "matchstring=%~1"
set "replacestring=%~3"

if "%~2."=="." goto :default2
set "searchpattern=%~2"
goto :start

set "matchstring=_"
set "replacestring=."

set "searchpattern=*%matchstring%*"

set "renamecount=0"
set "errorcount=0"

for /r %%f in ("%searchpattern%") do call :work "%%~dpf" "%%~nxf"
if %renamecount% EQU 0 echo No files renamed.
if %renamecount% EQU 1 echo Renamed %renamecount% file.
if %renamecount% GEQ 2 echo Renamed %renamecount% files.

if %errorcount% EQU 1 echo %errorcount% error renaming files.
if %errorcount% GEQ 2 echo %errorcount% errors renaming files.

goto :cleanexit

set matchedfilepath=%~1
set matchedfilename=%~2

rem You can't do it directly like this:
rem set "newfilename=%matchedfilename:%matchstring%=%replacestring%%"

for /F "usebackq delims=" %%g in (`echo set "newfilename=%%matchedfilename:%matchstring%=%replacestring%%%"`) do %%g
echo In path "%matchedfilepath%": Renaming "%matchedfilename%" to "%newfilename%"

rem delete the next line (goto :EOF) to make renaming active
goto :EOF

ren "%matchedfilepath%%matchedfilename%" "%newfilename%"
if %errorlevel% NEQ 0 goto :workerror
if not exist "%matchedfilepath%%newfilename%" goto :workerror
goto :workok

echo Rename "%matchedfilepath%%matchedfilename%" failed.
set /A errorcount=errorcount+1
goto :EOF

set /A renamecount=renamecount+1
goto :EOF

echo Syntax:
echo    %~nx0 ["match-string" ["search-pattern"] ["replace-string"]]
echo    Search for files matching "search-pattern" in current folder and through all 
echo    subfolders.  For each matched file, rename file by replacing "match-string" 
echo    with "replace-string".
echo    If "replace-string" is empty or not specified, rename file by deleting 
echo    "match-string".
echo    If "search-pattern" is empty, use "*matchstring*" as the "search-pattern".
echo    If "match-string" "search-pattern" and "replace-string" are all empty or not 
echo    specified, then defined defaults will be used.
echo    If "search-pattern" and/or "replace-string" are NOT empty then "match-string" 
echo    cannot be empty, 
goto :EOF

set "matchstring="
set "replacestring="
set "searchpattern="
set "renamecount="
set "errorcount="
set "matchedfilepath="
set "matchedfilename="
set "newfilename="
goto :EOF

Once you have run the batch file and are confident the correct files will be properly renamed, you can edit the file to remove the line(s) described to make renaming active, then run the batch file again.

To do that, find the two lines that are like this:

rem delete the next line (goto :EOF) to make renaming active
goto :EOF

Then, remove the line that says "goto :EOF" (or remove both lines).

Don't remove "goto :EOF" from any other place in the batch file (it can be found in a few places so be sure to remove the correct one).

If this isn't working for you, or if you want me to explain anything in the batch file, just let me know.

share|improve this answer

modifying what I found at this batch rename/move script this should work:

for /r %x in (*_*) do ren "%x" *.*
share|improve this answer
it echos the full pathname in quotes followed by . but the names in the directories are unchanged – PilotMom Feb 8 '11 at 5:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .