Mec*_*ash 15 cmd if-statement batch-file
当使用超过1个IF语句时,是否应遵循特殊准则?它们应该分组吗?我应该使用括号来包装命令吗?
使用的一个例子是:
IF EXIST somefile.txt IF EXIST someotherfile.txt SET var=somefile.txt,someotherfile.txt
Run Code Online (Sandbox Code Playgroud)
Mer*_*ham 32
是否有一个应遵循的特殊准则
没有"标准"方法来处理批处理文件,因为他们的绝大多数作者和维护者要么不理解编程概念,要么他们认为它们不适用于批处理文件.
但我是一名程序员.我习惯于编译,我习惯于调试.批处理文件未编译,您无法通过调试器运行它们,因此它们让我感到紧张.我建议你对你写的东西要特别严格,所以你可以非常肯定它会做你认为它做的事情.
有一些编码标准说:如果你写一个if声明,你必须使用大括号,即使你没有一个else条款.这样可以避免细微,难以调试的问题,并且可以明确地读取.我认为没有理由不能将此推理应用于批处理文件.
我们来看看你的代码吧.
IF EXIST somefile.txt IF EXIST someotherfile.txt SET var=somefile.txt,someotherfile.txt
Run Code Online (Sandbox Code Playgroud)
和IF语法,从命令HELP IF:
IF [NOT] ERRORLEVEL number command
IF [NOT] string1==string2 command
IF [NOT] EXISTS filename command
...
IF EXIST filename (
command
) ELSE (
other command
)
Run Code Online (Sandbox Code Playgroud)
所以你把它们IF作为命令链接起来.
如果您使用我上面提到的通用编码标准规则,您总是希望使用parens.以下是您为示例代码执行此操作的方法:
IF EXIST "somefile.txt" (
IF EXIST "someotherfile.txt" (
SET var="somefile.txt,someotherfile.txt"
)
)
Run Code Online (Sandbox Code Playgroud)
确保您干净地格式化,并进行某种形式的缩进.您可以在代码中执行此操作,并且应该在批处理脚本中执行此操作.
此外,您还应该养成始终引用文件名并正确引用的习惯.还有在一些空话HELP FOR,并HELP SET会帮助你,除去多余的报价再次引用字符串时.
编辑
从您的评论和重新阅读原始问题,您似乎想要构建一个逗号分隔的文件列表.对于这种情况,您可以简单地使用一堆if/ else语句,但这会导致一堆重复的逻辑,如果您有两个以上的文件,则根本不干净.
更好的方法是编写检查单个文件存在的子例程,如果指定的文件存在则附加到变量.然后只需为要检查的每个文件调用该子例程:
@ECHO OFF
SETLOCAL
REM Todo: Set global script variables here
CALL :MainScript
GOTO :EOF
REM MainScript()
:MainScript
SETLOCAL
CALL :AddIfExists "somefile.txt" "%files%" "files"
CALL :AddIfExists "someotherfile.txt" "%files%" "files"
ECHO.Files: %files%
ENDLOCAL
GOTO :EOF
REM AddIfExists(filename, existingFilenames, returnVariableName)
:AddIfExists
SETLOCAL
IF EXIST "%~1" (
SET "result=%~1"
) ELSE (
SET "result="
)
(
REM Cleanup, and return result - concatenate if necessary
ENDLOCAL
IF "%~2"=="" (
SET "%~3=%result%"
) ELSE (
SET "%~3=%~2,%result%"
)
)
GOTO :EOF
Run Code Online (Sandbox Code Playgroud)
Aac*_*ini 11
上面Merlyn给出的解释非常完整.但是,我想详细说明编码标准.
当链接多个IF时,在满足所有先前条件时执行最终命令; 这相当于一个AND运算符.我偶尔使用这种行为,但我清楚地通过一个名为AND的辅助Batch变量来表明我打算做什么:
SET AND=IF
IF EXIST somefile.txt %AND% EXIST someotherfile.txt SET var=somefile.txt,someotherfile.txt
Run Code Online (Sandbox Code Playgroud)
当然,这不是真正的And运算符,不能与ELSE子句结合使用.这只是程序员的帮助,可以提高很少使用的指令的易读性.
当我编写Batch程序时,我总是使用我设计的几个辅助变量,其唯一目的是编写更易读的代码.例如:
SET AND=IF
SET THEN=(
SET ELSE=) ELSE (
SET NOELSE=
SET ENDIF=)
SET BEGIN=(
SET END=)
SET RETURN=EXIT /B
Run Code Online (Sandbox Code Playgroud)
Merlyn建议,这些变量有助于以更清晰的方式编写批处理程序,并有助于避免细微的错误.例如:
IF EXIST "somefile.txt" %THEN%
IF EXIST "someotherfile.txt" %THEN%
SET var="somefile.txt,someotherfile.txt"
%NOELSE%
%ENDIF%
%NOELSE%
%ENDIF%
IF EXIST "%~1" %THEN%
SET "result=%~1"
%ELSE%
SET "result="
%ENDIF%
Run Code Online (Sandbox Code Playgroud)
我甚至有变量帮助写入WHILE-DO和REPEAT-UNTIL类似的结构.这意味着Batch变量可以在某种程度上用作预处理器值.
小智 5
批处理文件具有非常有限的逻辑功能,因此您可以希望得到的最好的解决方法是间接实现您想要的.这并不是说你应该觉得他们不如真正的语言 - 他们仍然需要同样注重细节和手动调试作为一个真正的应用程序.只是你需要更加努力地让他们以健壮的方式做你想做的事.
对于OP的问题,听起来您需要存在两个特定文件.只需使用一个计数器:
IF EXIST somefile.txt (
set /a file1_status=1
)
IF EXIST someotehrfile.txt (
set /a file2_status=1
)
set /a file_status_result=file1_status + file2_status
if %file_status_result% equ 2 (
goto somefileexists
)
goto exit
:somefileexists
IF EXIST someotherfile.txt SET var=...
:exit
Run Code Online (Sandbox Code Playgroud)
我的示例使用3个变量,但如果文件存在,您只需将1添加到file_result_status即可.但是,如果您希望稍后在批处理文件中进行更精细的控制,则可以像我一样记录每个文件的结果,这样您就不必继续检查文件是否存在.