0

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
echoquack
  • 3
  • 2
  • Is what is being [ENTER]ed within Bulk Rename Utility, in any way related to your stated issue? – Compo Jul 27 '23 at 15:09

1 Answers1

0

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 ECHOed 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.

Magoo
  • 77,302
  • 8
  • 62
  • 84
  • I tried it out and a few things jumped out. The first is that the string "Template" is not always the first 8 characters. Some files in the folders are named "foo-Template", "bar-Template" for sorting and legibility. I need it to change all instances of Template in the file/directory name. I managed to get it to rename the template.txt and other files after changing /a-d to /a:-d But, changing the dir for loop to /a:d did not result in all of the subfolders names changing. It seems to stop renaming at the third level of subdirectory (eg, foo/foo-bar/template-bar) – echoquack Aug 11 '23 at 20:45
  • Thanks for the revised code. It's working great, but is there a way to hide the output of the rename for loop? (it's processing through the entire 2023 Projects folder and may alarm basic users if they see the output) I tried using echo off before that section of code, but that didn't suppress the process output. I also tried another approach by changing sourcedir to Y:\2023 Projects\%projNumName% instead of Y:\2023 Projects hoping it would only process the new project folder, but doing that results in no names being changed. – echoquack Aug 14 '23 at 22:05
  • Did you read the part "The required REN commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO REN to REN to actually rename the files/directories." ? It's standard practice to just `echo` dangerous commands so that the correct operation of the batch can be analysed without actually **DOING** anything. Remove the `echo` before the `ren` and the rename will be **EXECUTED** instead of simply being displayed. The `ren` should generate no output, except if there's an error. – Magoo Aug 14 '23 at 22:12
  • Thanks for the prompt reply, yes, I removed echo from REN, but when the command runs on the 2023 Projects sourcedir, I see the output in the CMD window for every file and directory in 2023 Projects. – echoquack Aug 14 '23 at 22:32
  • I figured it out! I needed to set my projectName variable before setting the sourcedir variable. and I added in the full path "Y:\2023 Projects\%projectName%\*template*" in the for statement. Really appreciate your help with this, I learned a lot. – echoquack Aug 14 '23 at 23:06