我正在将脚本创建为.cmd,并且有一个命令可以将文件夹从“ test”重命名为“ test.old”,在某些情况下可能已经存在“ test.old”,从而造成重复错误,因此我实现了一个非常简化的解决方法,但是我试图弄清楚如何循环此命令,以便在存在重复项的情况下添加一个可变数字。
例如,如果test1.old将重命名为test2.old,如果存在则将其重命名为test3.old等。
1.50em
在.cmd脚本中最有效的方法是什么?
P.s我对脚本编写和编程都非常陌生
谢谢
答案 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
的新实例中执行重命名循环来完全避免了GOTOs
和CMD.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
命令时),特别是在迭代次数可能很大且批处理脚本的大小不小的情况下。