Reputation: 11
I'm trying to write a batch script to replace the filler XXXX in a given folder structure for future projects. The batch should be put in the folder and be run there.
e.g.:
and so on.
The filler is to be replaced with a user prompted project number. I've had this first shot at it, but the problem is, that it renames the first layer and then it can't find the others.
set /P oldString="To Replace:"
set /P newString="Replace with:"
call :rendirs %oldString% %newString%
:rendirs
for /f %%a in ('dir /s /ad /b "*%~1*"') do (call :rename %%a %~1 %~2)
:rename
set oldname=%~n1
call set newname=%%oldname:%~2=%~3%%
ren %oldname% %newname%
I've got the idea of cutting the for loop to 'dir /ad /b' so it doesn't involve the subfolders yet and recursively calling the :rendirs function for the subfolders, but it doesn't work.
:rendirs
for /f %%a in ('dir /ad /b' "*%~1*"') do (
call :rename %%a %~1 %~2
for /f %%i in ('dir /ad /b') do (
cd %%i
call :rendirs %~1 %~2
)
)
How do I make cd work inside the loop or how do I ensure the script can find the subdirectories?
Upvotes: 1
Views: 860
Reputation: 34899
I would accomplish your task using the following script (see the explanatory remarks in the code):
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_ROOT=%~dp0." & rem // (target root directory)
set "_MASK=%~1" & rem // (directory name pattern)
set "_SEARCH=%~2" & rem // (search string)
set "_REPLAC=%~3" & rem // (replacement string)
rem // Skip all actions if no search string is provided:
if defined _SEARCH (
rem /* Traverse directory hierarchy in reverse manner,
rem so lowest level directories come first: */
for /F "eol=| delims=" %%D in ('
dir /S /B /A:D-H-S "%_ROOT%\%_MASK%" ^| sort /R
') do (
rem // Store path and name of iterated directory:
set "DIRP=%%D" & set "NAME=%%~nxD"
rem // Toggle delayed expansion to avoide loss of `!`:
setlocal EnableDelayedExpansion
rem // Actually rename iterated directory here:
ren "!DIRP!" "!NAME:%_SEARCH%=%_REPLAC%!"
endlocal
)
)
endlocal
exit /B
Given it is named renaming.bat
, it should be used with the following arguments, based on your sample data and assuming XXXX
is to be replaced by 1234
:
renaming.bat "*_0XXXX*" "_0XXXX" "_01234"
Upvotes: 1
Reputation: 82217
You should use the move
command, instead of ren
, because it can rename full qualified pathnames.
Then the :rename
block looks like
:rename
set oldname=%1
call set newname=%%oldname:%~2=%~3%%
move %old_fullname% %newname%
BUT, you still have the problem of the renaming order.
First the top level directory is renamed, then all others will fail.
To solve this, you could reverse the dir list
Upvotes: 2