Batch file 用于在路径包含变量字符串的情况下递归重命名文件夹的批处理脚本

Batch file 用于在路径包含变量字符串的情况下递归重命名文件夹的批处理脚本,batch-file,Batch File,我有一个脚本,它从锚点位置(C:\Temp\Corporate Services)在文件夹结构中递归。对于树中的每个文件夹,如果路径包含单词Registers,则需要在Registers下面的所有子文件夹前面加上前缀(Reg)。 这是该树的一个示例-有400家公司具有相同的文件夹结构,如下所示: > tree C:. └───Temp └───Corporate Services ├───Company A │ ├───Agreements

我有一个脚本,它从锚点位置(C:\Temp\Corporate Services)在文件夹结构中递归。对于树中的每个文件夹,如果路径包含单词Registers,则需要在Registers下面的所有子文件夹前面加上前缀(Reg)。 这是该树的一个示例-有400家公司具有相同的文件夹结构,如下所示:

> tree
C:.

└───Temp
    └───Corporate Services
        ├───Company A
        │   ├───Agreements
        │   │   ├───2017
        │   │   └───2018
        │   └───Registers
        │       ├───2016
        │       ├───2017
        │       └───2018
        │           └───Folder1
        │               └───Folder2
        └───Company B
        │   ├───Agreements
        │   │   ├───2017
        │   │   └───2018
        │   └───Registers
        │       ├───2016
        │       ├───2017
        │       └───2018
        │           └───FolderX
        │               └───Folder Y
        └───Company C...
因此,如果完整路径为C:\Temp\Corporate Services\Registers\2016,则2016文件夹需要重命名为(REG)2017。2017年和2018年也是如此。编辑:树可以扩展到其他子文件夹中,因此也需要重命名这些子文件夹

我已经设法在树中递归,但在分析“registers”字符串的路径时遇到了问题。任何帮助都将不胜感激

@echo off
set /A o=0
echo o starts as %o%

call :treeProcess
rem goto:eof

:treeProcess
setlocal enabledelayedexpansion
set /A i=1
REM echo i is %i%

for /f "tokens=*" %%f in ('dir /ad /s /b "C:\Temp\Corporate Services"') do (

echo root: %%f


for /D %%d in (*) do (

    cd %%d


    Set str1=%%~f
    Set var=%str1:registers=%
    echo %var%

    REM if not "%var%"==%str1% echo found reg

    set /A o=%i%+1

    if %o%==2 goto :eof 
    if %o%==1 call :treeProcess
    cd ..
    )
ENDLOCAL
        )
:eof
exit /b 0
@ECHO关闭
SETLOCAL
设置“sourcedir=U:\sourcedir”
对于/f“delims=”%%a IN(
'dir/b/s/ad”%sourcedir%\*“'
)做(
对于(2016,12018)中的/L%%y,请执行以下操作(
如果“%%~na”==“%%y”代表(“%%~dpa.”)中的%%p,则执行IF/i“%%~np”==“注册”ECHO(REN“%%a”“(REG)%%y”
)
)
)
后藤:EOF
您需要更改
sourcedir
的设置以适应您的环境

所需的REN命令仅用于测试目的验证命令是否正确后,将
ECHO(REN
更改为
REN
,以实际重命名文件

首先,执行目录扫描,对于找到的每个目录,检查“名称”部分(
%%~na
)是否为目标年份之一
%%y

如果是,那么如果父目录的名称部分是“Registers”,则进行重命名

哦-顺便说一句-在
代码块中使用
:::-Comments
(括号中的行序列)不是一个好主意,因为
是一个可以打破代码块的标签。在
代码块中使用
REM

哦-刚刚意识到您希望重命名所有子目录,而不仅仅是
2016..2018

更简单的代码:

@ECHO关闭
SETLOCAL
设置“sourcedir=U:\sourcedir”
对于/f“delims=”%%a IN(
'dir/b/s/ad”%sourcedir%\*“'
)做(
对于(“%%~dpa.”中的%%p,执行IF/i“%%~np”==“寄存器”ECHO(REN“%%a”“(REG)%%~na”
)
)
后藤:EOF
  • 下一批中的SearchDir可能看起来有误,
    但是
    Dir/B/S/AD
    从给定的路径开始,递归地搜索最后一个元素,这样就可以高效地只返回匹配的文件夹
  • 这是枚举其中文件夹的
    for/d
    的起点
  • 回显到findstr可确保不再处理已具有前缀
    (REG)
    的文件夹
  • 从技术上讲,作为一个单行程序,当用
    %
    替换
    %
    时,它可以在cmd行中执行

示例树输出:

> tree
C:.

└───Temp
    └───Corporate Services
        ├───Company A
        │   ├───Agreements
        │   │   ├───2017
        │   │   └───2018
        │   └───Registers
        │       ├───(REG)201
        │       ├───(REG)201
        │       └───(REG)201
        └───Company B

您的代码有几个缺陷;其中一些是:

  • 您正在同一代码块(
    str1
    var
    o
    )中写入和读取变量,这需要:
  • 这里完全不需要
    dir
    的开关
    /R
    (我想您对备用数据流不感兴趣)
  • 您正在尝试递归调用子例程
    :treeProcess
    (自己调用),它在某些情况下可能会工作,但在这里不行,因为您已经递归地枚举了所有(子)目录(
    dir/S
    )无论如何,递归调用是非常危险的,例如,您可能很容易达到嵌套限制
  • 千万不要在代码块中使用
    样式的注释,因为它们可能会导致意外的结果
  • 有一个(注释掉的)
    调用:EOF
    ,应该是
    goto:EOF
  • 有一个(注释掉的)
    if
    比较带引号的字符串和不带引号的字符串,所以它永远不会是真的
无论如何,由于您只想重命名某个层次结构级别上的目录,我建议不要使用递归以避免意外更改。相反,我只处理专用的grand child目录中的目录:

@echo关闭
setlocal EnableExtensions DisableDelayedExpansion
rem//在此处定义常量:
设置“\u ROOT=C:\Temp\Corporate Services”
设置“_NAME=寄存器”
设置“_PREF=(REG)”
rem//枚举根目录的直接子目录:
对于(“%\u ROOT%\*”)中的/D%%A,请执行以下操作(
rem//尝试更改为特定的grand child目录:
2> nul pushd“%~A\%\u NAME%”和(
rem//枚举孙子目录并筛选它们:
对于/F“delims=”%%C in('
2^>nul dir/B/A:D“*”^ findstr/I/V/B/C:“%\u PREF%”
""做"(
rem//重命名尚未删除的目录:
ECHO ren“%%~C”“%\u PREF%%~C”
)
rem//从孙子目录返回:
邻苯二胺
)
)
端部
退出/B

编辑 要处理孙子孙女的子目录,也可以使用以下代码:

@echo关闭
setlocal EnableExtensions DisableDelayedExpansion
rem//在此处定义常量:
设置“\u ROOT=C:\Temp\Corporate Services”
设置“_NAME=寄存器”
设置“_PREF=(REG)”
rem//枚举根目录的直接子目录:
对于(“%\u ROOT%\*”)中的/D%%A,请执行以下操作(
rem//尝试更改为特定的grand child目录:
2> nul pushd“%~A\%\u NAME%”和(
rem//递归枚举孙子目录并对其进行筛选:
对于/F“delims=”%%C in('
2^>nul dir/S/B/A:D“*”^ findstr/I/V/R/C:\\\%\U PREF%[^\\]*$”
""做"(
rem//重命名尚未删除的目录:
ECHO ren“%%~C”“%\u PREF%%%%~nxC”
)
rem//从孙子目录返回:
邻苯二胺
)
)
端部
退出/B

更新了树,感谢LotPings提供的优秀样本。也适用
> tree
C:.

└───Temp
    └───Corporate Services
        ├───Company A
        │   ├───Agreements
        │   │   ├───2017
        │   │   └───2018
        │   └───Registers
        │       ├───(REG)201
        │       ├───(REG)201
        │       └───(REG)201
        └───Company B