搜索目录树并将一个字符串的实例替换为另一个字符串。

huangapple go评论65阅读模式
英文:

Search directory tree and replace instances of a string with another string

问题

以下是您提供的代码的翻译部分:

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

echo 注意:这将创建所有必要的项目模板文件夹。
echo[

set /p projNumName="请输入项目编号和名称(例如 23-000_我的项目名称):"

SET projectName=%projNumName%
SET sourcedir="Y:23 Projects\%projectName%"

MkDir "Y:23 Projects\%projNumName%"

xcopy "W:\_PROJECT TEMPLATES-do not delete_\ProjTemplate\"  "Y:023 Projects\%projectName%\" /e

PUSHD "%sourcedir%"
FOR /f "delims=" %%e IN ('dir /s /b /a:-d "Y:23 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:23 Projects\%projectName%\*template*" ^|sort /rev' ) DO (
 SET "dirname=%%~nxe"
 SET "dirname=!dirname:template=%projectname%!"
 REN "%%e" "!dirname!"
)

popd

dir/s /b /on "Y:23 Projects\%projectName%"

echo[
echo[
echo[
echo 项目文件夹和文件已复制到您的项目文件夹。
echo[
echo[
echo[
echo[

PAUSE

GOTO :EOF

另外,以下是您提供的第二段代码的翻译:

@echo off

echo 这将创建您的项目文件夹。
echo[

SET /p projectName="请输入项目编号和名称(例如 23-000_我的新项目):"

MkDir "Y:\%projectName%"
MkDir "T:\Final Project Files 2023\%projectName%"

xcopy "W:\_PROJECT TEMPLATES_\Template\" "Y:\%projectName%\" /e

echo[
echo 模板文件夹和文件已复制到新项目文件夹。
echo[
echo 将任何包含“Template”的文件夹和文件重命名以匹配您的新项目名称。
echo[

PAUSE

START "" "C:\Program Files\Bulk Rename Utility\Bulk Rename Utility.exe"

希望这可以帮助您理解这些代码的功能。如果您有任何进一步的问题,请随时提出。

英文:

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:23 Projects\%projectName%"

MkDir "Y:23 Projects\%projNumName%"

xcopy "W:\_PROJECT TEMPLATES-do not delete_\ProjTemplate\"  "Y:23 Projects\%projectName%\" /e


PUSHD "%sourcedir%"
FOR /f "delims=" %%e IN ('dir /s /b /a:-d "Y:23 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:23 Projects\%projectName%\*template*" ^|sort /rev' ) DO (
 SET "dirname=%%~nxe"
 SET "dirname=!dirname:template=%projectname%!"
 REN "%%e" "!dirname!"
 )
)


popd

dir/s /b /on "Y:23 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:-000_My New Project\Template-Folder1
Y:-000_My New Project\Template-Folder2
Y:-000_My New Project\Template-Folder2\Template.txt

I would like to have:

Y:-000_My New Project-000_My New Project-Folder1
Y:-000_My New Project-000_My New Project-Folder2
Y:-000_My New Project-000_My New Project-Folder2-000_My New Project.txt

答案1

得分: 0

非常重要:

批处理文件很少不启动。

第一条命令指示cmd不要回显命令。
第二个命令在本地环境中建立一个具有父环境的副本。

本地环境在批处理终止时退出,恢复父环境。因此,任何在代码的其余部分运行时更改的变量都会被撤销。

目前,您的代码将projectName设置到该cmd实例的环境中,直到显式删除它。

setlocal还可以采用一些参数,这些参数会改变本地环境内cmd的行为 - 从提示符处查看setlocal /?以获取文档。

默认情况下,启用EXTENSIONS并禁用DELAYEDEXPANSION

由于此代码使用了delayedexpansion(请参阅Stephan的DELAYEDEXPANSION链接),您需要使用以下内容作为前两行:

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

*--------问题的重点

xcopy之后添加以下内容:

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!"
 )
)

在应用到实际数据之前,始终要对测试目录进行验证。

这会扫描新创建的目录子树中的文件,如果文件的前8个字符是template(不区分大小写),则将文件重命名为projectname与文件名(去除前8个字符)相连 - 请从提示符处查看set /?以获取文档。

然后,该过程将重复进行以处理目录名称。

注意:
所需的REN命令仅用于测试目的。在验证命令正确后,将ECHO REN更改为REN以实际重命名文件/目录。

--- 修订版本 -----

@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

您需要更改分配给sourcedir的值以适应您的情况。此列表使用适合我的系统的设置。我故意在名称中包含空格,以确保正确处理空格。

此版本使用dir查找template的实例。对于我来说,:被文档化为可选的 - 对我来说,它没有问题。

目录名称未正确处理的问题应该通过^|sort /rev修复。^需要告诉cmd管道是要执行的命令的一部分,而不是for的一部分。

通过将目录名倒序排序,每次找到子目录时都会在其父目录之前出现,因此首先重命名。

英文:

Very important:

It's rare for a batch file to not start

@echo off
setlocal

The first command instructs cmd to NOT echo commands<br>
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 &quot;delims=&quot; %%e IN (&#39;dir /s /b /a-d &quot;Y:\%projectName%\*&quot; &#39; ) DO (
 SET &quot;filename=%%~nxe&quot;
 IF /i &quot;!filename:~0,8!&quot; == &quot;template&quot; (
  SET &quot;filename=%projectname%!filename:~8!&quot;
  ECHO REN &quot;%%e&quot; &quot;!filename!&quot;
 )
)
FOR /f &quot;delims=&quot; %%e IN (&#39;dir /s /b /ad &quot;Y:\%projectName%\*&quot; &#39; ) DO (
 SET &quot;dirname=%%~nxe&quot;
 IF /i &quot;!dirname:~0,8!&quot; == &quot;template&quot; (
  SET &quot;dirname=%projectname%!dirname:~8!&quot;
  ECHO REN &quot;%%e&quot; &quot;!dirname!&quot;
 )
)

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:<br>
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 &quot;sourcedir=u:\your files&quot;
SET &quot;projectName=23-000_My New Project&quot;

PUSHD &quot;%sourcedir%&quot;
FOR /f &quot;delims=&quot; %%e IN (&#39;dir /s /b /a-d &quot;%projectName%\*template*&quot; &#39; ) DO (
 SET &quot;filename=%%~nxe&quot;
 SET &quot;filename=!filename:template=%projectname%!&quot;
 ECHO REN &quot;%%e&quot; &quot;!filename!&quot;
)

FOR /f &quot;delims=&quot; %%e IN (&#39;dir /s /b /ad &quot;%projectName%\*template*&quot; ^|sort /rev&#39; ) DO (
 SET &quot;dirname=%%~nxe&quot;
 SET &quot;dirname=!dirname:template=%projectname%!&quot;
 ECHO REN &quot;%%e&quot; &quot;!dirname!&quot;
 )
)

popd

dir/s /b /on &quot;u:\your files&quot;

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.

huangapple
  • 本文由 发表于 2023年7月27日 22:52:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/76780966.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定