Windows批处理:即使errorlevel 1,REN也不会停止

时间:2016-01-28 04:05:02

标签: windows batch-file cmd

我使用REN查找具有特定命名模式的文件并修改它们,如下所示:

REN "?%var1%?%var2%.S16" "?%var1%?%var3%.S16"

这将找到所有文件,如aXaY.S16,bXaY.S16,cXbY.S16(等),并将它们重命名为aXaZ.S16,bXaZ.S16,cXbZ.S16(等)。如果它找到它正在寻找的东西,它就可以正常工作。但是存在一个问题:如果遇到错误,REN不会停止操作。

为了证明这种情况,我的脚本如下:

@echo off
set /p var1=Enter first var: 
set /p var2=Enter second var:
set /p var3=Change second var to:

echo Searching for all files matching ?%var1%?%var2%.S16

REN "?%var1%?%var2%.S16" "?%var1%?%var3%.S16"
echo Errorlevel: %errorlevel%
IF ERRORLEVEL 1 goto :FAIL
echo Success!
PAUSE
goto :eof

:FAIL
echo I done goofed!
PAUSE
exit

我在包含几百个文件的文件夹中运行它。我搜索了匹配的文件?0?a.S16(其中有大约40个结果)并要求它更改' a'知道具有此名称的文件已存在且应该产生冲突。

这是控制台输出(为简洁起见缩短):

Enter first var: 0
Enter second var:a
Change second var to:c
Searching for all files matching ?0?a.S16
A duplicate file name exists, or the file
cannot be found.
A duplicate file name exists, or the file
cannot be found.
A duplicate file name exists, or the file
cannot be found.
...(etc)...
Errorlevel: 1
I done goofed!
Press any key to continue . . .

正如预期的那样,关于重复的投诉持续了大约40行。正如您所看到的,Errorlevel在流程结束时返回1,而不是在出现问题的第一个迹象时退出,这就是我所做的事情。

我确实考虑过将其传递给FOR / f,但我不知道如何通过它传递搜索掩码。我知道FOR支持' *'通配符,但据我所知,它并不支持'?'和REN一样。一种可能的替代方案是以某种方式使用正则表达式,但尽管尝试,我仍然无法绕过它们。

任何线索?非常感谢你看一看。

2 个答案:

答案 0 :(得分:1)

是的,您已经记录了REN命令的工作原理 - 即使在重命名失败后它仍会继续完成,然后如果至少有一个重命名失败则报告ERRORLEVEL 1。

如果要在第一个错误时暂停处理,则必须编写自己的循环来重命名每个文件,一次一个。您不应该使用简单的FOR循环,因为它可以在扫描整个目录之前开始迭代,因此您可能会冒两次重命名同一文件的风险。安全的做法是使用FOR / F与DIR / B / A-D相结合。

@echo off
set /p var1=Enter first var: 
set /p var2=Enter second var:
set /p var3=Change second var to:

echo Searching for all files matching ?%var1%?%var2%.S16

for /f "eol=: delims=" %%F in (
  'dir /b /a-d "?%var1%?%var2%.S16"'
) do ren "%%F" "?%var1%?%var3%.S16" || goto :break
:break
echo Errorlevel: %errorlevel%
IF ERRORLEVEL 1 goto :FAIL
echo Success!
PAUSE
goto :eof

:FAIL
echo Errorlevel: %errorlevel%
echo I done goofed!
PAUSE
exit

注意 - REN使用的通配符规则根本不直观。您应该查看How does the Windows RENAME command interpret wildcards?以确保获得预期的结果。

答案 1 :(得分:0)

替换你ren命令
FOR /f "delims=" %%x IN ('dir /b /a-d "%sourcedir%\?%var1%?%var2%.S16" 2^>nul') DO REN "%sourcedir%\%%x" "?%var1%?%var3%.S16"&IF ERRORLEVEL 1 ECHO failed AT %%x&goto :EOF 

note 这是我测试的直接补丁,我将sourcedir设置为测试目录。在您的情况下,您需要进行适当的调整。

这使得目录列表以基本形式没有目录,然后将每个文件名分配给%%x然后尝试重命名并解释结果errorlevel。如果失败,请显示良好衡量标准的名称并保释。

[edit] 2^>nul添加到dir命令中。

这会导致dir错误(例如"找不到文件")定向到无处。插入符号^)需要告诉cmd >dir命令的一部分,而不是for