循环重命名命令重复cmd / batch

时间:2018-07-13 01:56:11

标签: batch-file cmd

我正在将脚本创建为.cmd,并且有一个命令可以将文件夹从“ test”重命名为“ test.old”,在某些情况下可能已经存在“ test.old”,从而造成重复错误,因此我实现了一个非常简化的解决方法,但是我试图弄清楚如何循环此命令,以便在存在重复项的情况下添加一个可变数字。

例如,如果test1.old将重命名为test2.old,如果存在则将其重命名为test3.old等。

1.50em

在.cmd脚本中最有效的方法是什么?

P.s我对脚本编写和编程都非常陌生

谢谢

2 个答案:

答案 0 :(得分:1)

您可以使用它:

REN "%userprofile%\AppData\Local\test" "test.old"
if %errorlevel% == 1 goto :TESTDUP
goto :END
:TESTDUP
REN "%userprofile%\AppData\Local\test" "test%it%.old"
if %errorlevel% == 0 goto :END
set /A it+=1
goto :TESTDUP
:END

如果第一个REN不起作用,请尝试重命名该文件夹,直到找到可用的名称为止

答案 1 :(得分:0)

重试基于errorlevel的重命名操作不是一个好主意,因为重命名也可能由于多种原因(除了重复的名称冲突)而失败。例如,当源不存在或您没有足够的权限来重命名对象或使用目标时,...

更通用的方法将是这样

@echo off
setlocal EnableExtensions DisableDelayedExpansion

set "FSObjToRename=PathToFileOrFolder"
set /a "start#=1, maxRetries=10000, end#=start#+maxRetries"
set "q=""
for %%F in ("%FSObjToRename%") do (
    set "SpawnCommand=for /L %%# in (%start#%,1,%end#%) do @if not exist %%q%%%FSObjToRename%.%%#.old%%q%% (ren %%q%%%FSObjToRename%%%q%% %%q%%%%~nxF.%%#.old%%q%% & exit)"

    REM This is a more readable form of the SpawnCommand:
    REM for /L %%# in (%start#%,1,%end#%) do @if not exist "%FSObjToRename%.%%#.old" (ren "%FSObjToRename%" "%%~nxF.%%#.old" & exit)
)

if exist "%FSObjToRename%" cmd /e:on /v:off /d /s /c "%SpawnCommand%"

上面的代码通过在:Labels的新实例中执行重命名循环来完全避免了GOTOsCMD.EXE,因此可以通过exit命令来中断循环,但是如果字符串因为SpawnCommand看起来很奇怪和混乱(主要是因为%%q%%隐藏了批处理文件解析器中的引号),然后少量重试,可以像这样重写循环< / p>

if exist "%FSObjToRename%" for %%F in ("%FSObjToRename%") do (
    for /L %%# in (%start#%,1,%end#%) do (
        if not exist "%FSObjToRename%.%%#.old" (ren "%FSObjToRename%" "%%~nxF.%%#.old" & goto :break)
    )
)
:break

goto内使用FOR loop将阻止loop body的执行,但不会中断到loop iterator(它将盲目地计入%end#%),因此在执行goto :break与实际进入:break之间会有一定的延迟,该延迟取决于迭代次数

重试次数被视为small的内容完全取决于计算机的性能。对于当今的计算机,即使进行100000次迭代,您也可能不会注意到延迟。对于足够小的重试,后者的性能要比启动cmd的新实例稍好,但是前者在处理任意重试方面更强大。

应尽可能避免使用向后GOTOs(当目标Label高于GOTO命令时),特别是在迭代次数可能很大且批处理脚本的大小不小的情况下。