EDIT:
New Code thanks to the help of @Magoo
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
echo NOTE: This will create all necessary project template folders.
echo[
set /p projNumName=" Enter Project Number & Name (ex. 23-000_My Project Name): "
SET projectName=%projNumName%
SET sourcedir="Y:\2023 Projects\%projectName%"
MkDir "Y:\2023 Projects\%projNumName%"
xcopy "W:\_PROJECT TEMPLATES-do not delete_\ProjTemplate\" "Y:\2023 Projects\%projectName%\" /e
PUSHD "%sourcedir%"
FOR /f "delims=" %%e IN ('dir /s /b /a:-d "Y:\2023 Projects\%projectName%\*template*" ' ) DO (
SET "filename=%%~nxe"
SET "filename=!filename:template=%projectname%!"
REN "%%e" "!filename!"
)
FOR /f "delims=" %%e IN ('dir /s /b /ad "Y:\2023 Projects\%projectName%\*template*" ^|sort /rev' ) DO (
SET "dirname=%%~nxe"
SET "dirname=!dirname:template=%projectname%!"
REN "%%e" "!dirname!"
)
)
popd
dir/s /b /on "Y:\2023 Projects\%projectName%"
echo[
echo[
echo[
echo Template folders and files have been copied to your project folder.
echo[
echo[
echo[
echo[
PAUSE
GOTO :EOF
end of edit
I found this post, but I don't have enough rep points to comment on it. It's effectively nearly identical to my situation. I can't use PowerShell, and I need to recursively search for a string ("Template") and replace it with another, which the user inputs.
Here are the important parts of the code I have so far:
@echo off
echo THIS WILL CREATE YOUR PROJECT FOLDERS
echo[
SET /p projectName="Enter Project Number and Name (ex. 23-000_My New Project): "
MkDir "Y:\%projectName%"
MkDir "T:\Final Project Files 2023\%projectName%"
xcopy "W:\_PROJECT TEMPLATES_\Template\" "Y:\%projectName%\" /e
echo[
echo Template folders and files have been copied to the new project folder.
echo[
echo Rename any instances of "Template" to match your new project name.
echo[
PAUSE
START "" "C:\Program Files\Bulk Rename Utility\Bulk Rename Utility.exe"
The code I have works for the situation, but I'm attempting to eliminate the last bit where Bulk Rename Utility launches and requires the user to manually bulk rename the folders and files that contain "Template".
What I get now is:
Y:\23-000_My New Project\Template-Folder1
Y:\23-000_My New Project\Template-Folder2
Y:\23-000_My New Project\Template-Folder2\Template.txt
I would like to have:
Y:\23-000_My New Project\23-000_My New Project-Folder1
Y:\23-000_My New Project\23-000_My New Project-Folder2
Y:\23-000_My New Project\23-000_My New Project-Folder2\23-000_My New Project.txt
Very important:
It's rare for a batch file to not start
@echo off
setlocal
The first command instructs cmd
to NOT echo commands
The second establishes a local environment with a copy of the parent environment.
The local environment is exited when the batch terminates, restoring the parent environment. Consequently, any variables altered when the rest of the code runs are undone.
As it stands, your code would set projectName
into the environment for that instance of cmd
until it is explicitly removed.
setlocal
can also take some arguments that alter cmd
's behaviour within the local environment - see setlocal /?
from the prompt for documentation.
By default, EXTENSIONS
is enabled and DELAYEDEXPANSION
is disabled.
Since this code uses delayedexpansion
(see Stephan's DELAYEDEXPANSION link) you need to use
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
as your first two lines.
*-------- the meat of the matter
Just after the xcopy
add:
FOR /f "delims=" %%e IN ('dir /s /b /a-d "Y:\%projectName%\*" ' ) DO (
SET "filename=%%~nxe"
IF /i "!filename:~0,8!" == "template" (
SET "filename=%projectname%!filename:~8!"
ECHO REN "%%e" "!filename!"
)
)
FOR /f "delims=" %%e IN ('dir /s /b /ad "Y:\%projectName%\*" ' ) DO (
SET "dirname=%%~nxe"
IF /i "!dirname:~0,8!" == "template" (
SET "dirname=%projectname%!dirname:~8!"
ECHO REN "%%e" "!dirname!"
)
)
Always verify against a test directory before applying to real data.
This scans the newly-created directory subtree for files and if the first 8 characters are template
(in either case) then the file is renamed to the projectname concatenated with the filename(except for the first 8 characters) - see set /?
from the prompt for docco.
That process is then repeated for the directory names.
Note:
The required REN commands are merely ECHO
ed for testing purposes. After you've verified that the commands are correct, change ECHO REN
to REN
to actually rename the files/directories.
--- revision -----
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=u:\your files"
SET "projectName=23-000_My New Project"
PUSHD "%sourcedir%"
FOR /f "delims=" %%e IN ('dir /s /b /a-d "%projectName%\*template*" ' ) DO (
SET "filename=%%~nxe"
SET "filename=!filename:template=%projectname%!"
ECHO REN "%%e" "!filename!"
)
FOR /f "delims=" %%e IN ('dir /s /b /ad "%projectName%\*template*" ^|sort /rev' ) DO (
SET "dirname=%%~nxe"
SET "dirname=!dirname:template=%projectname%!"
ECHO REN "%%e" "!dirname!"
)
)
popd
dir/s /b /on "u:\your files"
GOTO :EOF
You would need to change the value assigned to sourcedir
to suit your circumstances. The listing uses a setting that suits my system. I deliberately include spaces in names to ensure that the spaces are processed correctly.
This version uses dir
to find the instances of template
. The :
is documented as being optional - for me, it worked without.
The issue with the directory name not being correctly processed should be fixed by the ^|sort /rev
. The ^
is required to tell cmd
that the pipe is part of the command to be executed, not of the for
.
By sorting the directorynames in reverse, every child directory found appears before its parent, so is renamed first.