Page 1 of 1
DOS Batch / XP Command prompt file rename to remove spaces.
Posted: 25 Jan 2008 14:23
by jaffamuffin
Hi all
Does anyone have a script or algorithm for searching through a directory tree of files and renaming any that have spaces in the file names and directory names? e.g. to have a _ instead of a space. Most files won't have a space.
The code below does it but it's not great and it's slow (when you're checking 50,000+ files) and I know there must be a better way. I have unixutils binaries, and confirmation or failure of the operation is required, as the rest of my scripts can't proceed unless the files are renamed properly.
Code: Select all
@echo off
REM %1 is top level of dir heirachy to be checked e.g. c:\checkthesefiles\
SETLOCAL ENABLEEXTENSIONS
SETLOCAL ENABLEDELAYEDEXPANSION::REMOVE SPACES FROM FILES NAMES
SET UNTMP=C:\UNTMP\
if not exist !UNTMP! MKDIR !UNTMP!
::check for spaces
DIR %1 /B /S | grep "\ ">nul
IF NOT ERRORLEVEL 1 SET ERRNONE=TRUE
IF !ERRNONE!==TRUE (
ECHO [WW] Filenames containing Spaces were found - Removing spaces...
FOR /R %1 %%G IN (.) DO ECHO !CD! & CALL :spaceRemove "%%G"
ECHO.[II] SPACES SUBSTITUTED FOR UNDERSCORES...COMPLETE!
) ELSE (
ECHO [II] No spaces in filename found.
)
GOTO:EOF
:spaceRemove
SET SUBDIRLISTORIG=!UNTMP!SUBDIRLISTORIG.TXT
SET SUBDIRLISTNEW=!UNTMP!SUBDIRLISTNEW.TXT
SET SUBDIRLISTCOMB=!UNTMP!SUBDIRLISTCOMB.TXT
CD /D %1
DIR /ON /B > !SUBDIRLISTORIG!
DIR /ON /B | sed "s/ /_/g" > !SUBDIRLISTNEW!
paste -d, !SUBDIRLISTORIG! !SUBDIRLISTNEW! > !SUBDIRLISTCOMB!
FOR /F "tokens=1,2 delims=," %%G IN (!SUBDIRLISTCOMB!) DO (
IF EXIST "%%G" (
REM DIR,OLDNAME,NEWNAME
REM ECHO !CD!,%%G,%%H >> !UNTMP!RENAMELOG.TXT
REN "%%G" %%H
REM
) ELSE (
ECHO [EE] ERROR FILE DON'T EXIST
GOTO:error3 "%%G"
)
)
GOTO:EOF
Posted: 30 Jan 2008 22:53
by DosItHelp
jaffamuffin,
This should do the trick
Code: Select all
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
CD /D "%~1"
for /f "delims=" %%A in ('dir /b /s') do (
set "f=%%~A"
set "f=!f: =_!" &rem replace space with underscore
if "%%~A" NEQ "!f!" echo ren "%%~A" "!f!"
)
DOS IT HELP
Posted: 31 Jan 2008 18:17
by jaffamuffin
Thanks!
Unfortunately though, that runs into similar problems,
1. It starts to rename the top level dirs before the subdirs. Once it does this it can't find the subdirs and errors.
2. the REN command is too weak for this, you can't rename a file including path to another file including path.(or can you?) The original script above Cds into each dir and perfoms the ren on each file there.
Plus, this seemed to remove spaces in the whole path right back to drive letter, %1 should be the root for this operation.
However the script is very useful and I took it and changed it to this:
Code: Select all
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
REM directories first - must sort as renaming a top level dir makes the sub dirs inaccessible
CD /D "%~1"
for /f "delims=" %%A in ('dir /AD /b /s ^| sort /r') do (
set "f=%%~nA"
set "g=%%~A"
set "f=!f: =_!" &rem replace space with underscore
cd /d "%%~A" & cd ..
if "%%~A" NEQ "!~g!" REN "%%~nA" "!f!"
)
REM Files second
CD /D "%~1"
for /f "delims=" %%A in ('dir /A-D /b /s') do (
set "f=%%~nxA"
set "g=%%~A"
set "f=!f: =_!" &rem replace space with underscore
cd /d "%%~dpA"
if "%%~A" NEQ "!~g!" REN "%%~A" "!f!"
)
This seems to work well for me... Could it be tidied in a way?
I just tested on a bunch of New Folders and New Text Documents.txt nested a few times in each other in a single grandparent directory.
Posted: 31 Jan 2008 21:58
by DosItHelp
jaffamuffin,
I see your point. Smart move of you to just reverse the output list.
Well since after reversing the order you move your way bottom up, it should be ok to rename the directories in the same loop, because if you hit a directory then for sure you have already processed its content, right?
So how about this:
Code: Select all
SETLOCAL ENABLEDELAYEDEXPANSION
CD "C:\Web\_Material\tmp"||GOTO:EOF
for /f "delims=" %%A in ('"dir /b /s|sort /r"') do (
set "f=%%~nxA"
set "f=!f: =_!" &rem replace space with underscore
if "%%~nxA" NEQ "!f!" (
echo.cd "%%~dpA"
echo.ren "%%~nxA" "!f!"
)
)
Posted: 01 Feb 2008 15:48
by jaffamuffin
Yep, well done
Didn't know about using the double quotes to eliminate the caret before the pipe. Does this technique require the use of "delims=" ?
I took this and changed it into a bit more flexible will take search and replace params and will do files, dirs or both.
Code: Select all
@echo off
REM %4- PATH TO SEARCH FROM
REM %2 - "TEXT TO FIND"
REM %3 - "TEXT TO REPLACE WITH"
REM %1 - -both OR -files OR -dirs
REM example - replace.bat -files new old C:\tmp -- Will replace old with new in all filenames in c:\tmp and below
SETLOCAL ENABLEDELAYEDEXPANSION
SET MODE=%~1
SET FIND=%~2
SET REPLACE=%~3
CD /D "%~4"||GOTO:EOF
rem default is rename only files
SET ACTION=NOTFOUND
IF %MODE%==-both SET ACTION="dir /b /s|sort /r"
IF %MODE%==-dirs SET ACTION="dir /b /s /ad|sort /r"
IF %MODE%==-files SET ACTION="dir /b /s /a-d|sort /r"
if %ACTION%==NOTFOUND ECHO Please select -both, -files, or -dirs & goto:eof
for /f "delims=" %%A in ('%ACTION%') do (
set "f=%%~nxA"
set "f=!f:%FIND%=%REPLACE%!" &rem find and replace
if "%%~nxA" NEQ "!f!" (
cd "%%~dpA"
ren "%%~nxA" "!f!"
)
)
GOTO:EOF
Posted: 01 Feb 2008 21:37
by DosItHelp
Awesome
Re: DOS Batch / XP Command prompt file rename to remove spac
Posted: 16 Dec 2011 04:39
by budi.com
you guys are awesome. i have no clue how to read the codes. i stumbled upon this page trying to find a simple drophere.bat file that i can use to drop a couple of files in order to rename the underscores within the filenames to "-"
eg. abc_def.txt to abc-def.txt
or a simple runthis.bat that will do the rename for all the files in the same folder as the runthis.bat
i hope you gents can point me in the right directions
have a pleasant holiday
Re: DOS Batch / XP Command prompt file rename to remove spac
Posted: 16 Dec 2011 10:10
by jaffamuffin
My script above will do that. Paste it into a file called replace.bat. Then
replace.bat -files new old C:\tmp
i.e:
Replace.bat -files "-" " " c:\filestorename\
Re: DOS Batch / XP Command prompt file rename to remove spac
Posted: 16 Dec 2011 10:12
by jaffamuffin
Oops for underscore to hyphen you want
replace.bat -files "-" "_" C:\files\to\rename
Or maybe the other way.. Damn looks like ive mixed the old and new up in the example ?
Re: DOS Batch / XP Command prompt file rename to remove spac
Posted: 17 Dec 2011 10:42
by budi.com
thanks jaffamuffin. i'll give it a spin
Re: DOS Batch / XP Command prompt file rename to remove spac
Posted: 18 Dec 2011 09:29
by dbenham
Nice script
I've made a few improvements, some more important than others:
1) The original will corrupt any renamed file/dir that contains ! in the name. That character is not seen often, but you may be sorry if you happen to run into one and use the original code
The problem is the expansion of the FOR variable when delayed expansion is enabled. I postpone enabling delayed expansion and toggle it on and off within the loop. I needed to create a few more vars to compensate.
2) The rename can fail if the new name already exists (duplicate) or if the name is empty after the substitution. The REN command gives an error message, but doesn't tell you what file/dir failed. I simply added a message indicating the failed file/dir that only fires upon failure.
3) I improved the argument parsing code at the top to support special characters like & or ^. The original would prevent you from replacing "&" with "_and_".
I haven't tested these changes
I'm sure the concepts of the fixes are correct, but I may have introduced a bug, so test carefully.
Code: Select all
@echo off
REM %4- PATH TO SEARCH FROM
REM %2 - "TEXT TO FIND"
REM %3 - "TEXT TO REPLACE WITH"
REM %1 - -both OR -files OR -dirs
REM example - replace.bat -files new old C:\tmp -- Will replace old with new in all filenames in c:\tmp and below
SETLOCAL DisableDelayedExpansion
SET "MODE=%~1"
SET "FIND=%~2"
SET "REPLACE=%~3"
CD /D "%~4"||GOTO:EOF
rem default is rename only files
SET ACTION=NOTFOUND
IF "%MODE%"=="-both" SET ACTION="dir /b /s|sort /r"
IF "%MODE%"=="-dirs" SET ACTION="dir /b /s /ad|sort /r"
IF "%MODE%"=="-files" SET ACTION="dir /b /s /a-d|sort /r"
if %ACTION%==NOTFOUND ECHO Please select -both, -files, or -dirs & goto:eof
for /f "delims=" %%A in ('%ACTION%') do (
set "f=%%~nxA"
set "p=%%~dpA"
setlocal enableDelayedExpansion
set "f2=!f:%FIND%=%REPLACE%!" &rem find and replace
if "!f2!" NEQ "!f!" (
cd "!p!"
ren "!f!" "!f2!" || echo Unable to rename "!p!!f!"
)
endlocal
)
GOTO:EOF
Dave Benham