首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带分支的批处理文件- if语句的替代

带分支的批处理文件- if语句的替代
EN

Stack Overflow用户
提问于 2014-06-11 10:26:52
回答 3查看 554关注 0票数 1

我有一个批处理文件,它接受操作模式作为参数,并按照它的特定顺序运行几个命令,我想知道除了有大量的IF语句之外,还有其他方法来处理这个批处理文件吗?

这不是真正的代码,只是显示了流程。

代码语言:javascript
复制
Get MODE as Parameter
If MODE=TYPE1 or MODE=TYPE2 then
    Run Command A
endif

If MODE=TYPE1 or MODE=TYPE3 then
    Run Command B
endif

If MODE=TYPE3 then
    Run Command C
endif
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-06-11 11:10:00

代码语言:javascript
复制
@echo off
    setlocal enableextensions

    set "MODE=%~1"
    set "WHENMODE=call :testCase "%MODE%" "

    %WHENMODE% TYPE1 TYPE2 && (
        echo Run command A
    )

    %WHENMODE% TYPE1 TYPE3 && (
        echo Run command B
    )

    %WHENMODE% TYPE3 && (
        echo Run command C
    )

    endlocal
    exit /b

:testCase value test1 test2 ... testn
    if "%~2"==""    exit /b 1
    if "%~1"=="%~2" exit /b 0
    shift /2 & goto %0

%WHENMODE%的定义仅仅是审美的。没有装饰的相同代码

代码语言:javascript
复制
@echo off
    setlocal enableextensions

    set "MODE=%~1"

    call :testCase "%MODE%" TYPE1 TYPE2 && echo Run command A
    call :testCase "%MODE%" TYPE1 TYPE3 && echo Run command B
    call :testCase "%MODE%" TYPE3       && echo Run command C

    endlocal
    exit /b

:testCase value test1 test2 ... testn
    if "%~2"==""    exit /b 1
    if "%~1"=="%~2" exit /b 0
    shift /2 & goto %0
票数 2
EN

Stack Overflow用户

发布于 2014-06-11 11:55:21

首先,我认为谨慎的做法是展示如何处理IF语句。批处理IF不支持或逻辑。下面模拟OR:

代码语言:javascript
复制
@echo off
setlocal enableDelayedExpansion
set "mode=%~1"

set "aModes= TYPE1 TYPE2 "
set "bModes= TYPE1 TYPE3 "
set "cModes= TYPE3 "

if "!aModes:%mode%=!" neq "!aModes!" echo command A
if "!bModes:%mode%=!" neq "!bModes!" echo command B
if "!cModes:%mode%=!" neq "!cModes!" echo command C

现在寻找可能替代IF的方法。

( 1)我能想到的一件半实用的事情是用这种模式作为标签,但我不喜欢它。不必要的调用使用速度可能会大大减慢。您必须确保模式值被控制,否则您将收到难看的错误消息。此外,由于相同的模式运行多个命令,所以这些命令在代码中被复制。

代码语言:javascript
复制
@echo off
setlocal
set "mode=%~1"

call :%MODE%
:: remainder of logic
exit /b

:TYPE1
echo command A
echo command B
exit /b

:TYPE2
echo command A
exit /b

:TYPE3
echo command B
echo command C
exit /b

如果命令A和/或B和/或C是一个复杂的命令块,那么可以将它们变成自己的标记子例程,并在适当的情况下生成CALLed。这将防止复杂逻辑的复制。

2)另一种可能是带有条件命令执行的FINDSTR,但这比如果执行要慢,而且比较尴尬。唯一的优点是它不需要额外的变量来实现OR逻辑。

代码语言:javascript
复制
@echo off
setlocal
set "mode=%~1"

echo %mode%|>nul findstr "TYPE1 TYPE2" && echo command A
echo %mode%|>nul findstr "TYPE1 TYPE3" && echo command B
echo %mode%|>nul findstr "TYPE3"       && echo command C

请注意,如果您的模式类似于BC和ABCD,那么上面的模式将无法工作,因为BC包含在ABCD中。可以通过引入一些括号来处理这一问题。

代码语言:javascript
复制
@echo off
setlocal
set "mode=%~1"

echo {%mode%}|>nul findstr "{TYPE1} {TYPE2}" && echo command A
echo {%mode%}|>nul findstr "{TYPE1} {TYPE3}" && echo command B
echo {%mode%}|>nul findstr "{TYPE3}"         && echo command C

最后,您可以使用MC ND的简单宏的想法,使上述看起来更优雅一点。

代码语言:javascript
复制
@echo off
setlocal
set "mode=%~1"

set "whenMode=echo {%mode%}|>nul findstr"

%whenMode% "{TYPE1} {TYPE2}" && echo command A
%whenMode% "{TYPE1} {TYPE3}" && echo command B
%whenMode% "{TYPE3}"         && echo command C

3)您可以非常喜欢并使用一种先进的带参数的批处理宏技术。这是一个对带有参数的批处理宏的技术和开发的良好入门

设置宏需要大量的神秘代码,但是一旦定义了宏,它就非常容易使用,而且速度非常快。最好的部分是它可以用于任何变量。在下面的示例中,我将它与MODE1和MODE2一起使用。

代码语言:javascript
复制
@echo off
setlocal disableDelayedExpansion
set "mode1=%~1"
set "mode2=%~2"

:: define LF as a Line Feed (newline) character
set ^"LF=^

^" Above empty line is required - do not remove

:: define a newline with line continuation
set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"

:: define a when macro that takes arguments
set when=%\n%
for %%# in (1 2) do if %%#==2 (setlocal enableDelayedExpansion^&for /f "tokens=1*" %%1 in ("!args!") do (%\n%
  set "test= %%~2 "%\n%
  for /f %%M in ("!%%1!") do (%\n%
    if "!test:%%M=!" neq "!test!" (%\n%
      endlocal%\n%
      endlocal%\n%
      (call )%\n%
    ) else (%\n%
      endlocal%\n%
      endlocal%\n%
      (call)%\n%
    )%\n%
  )%\n%
)) else setlocal^&set args=

:: ------- End of Initialization ---------------------

(%when% mode1 "TYPE1 TYPE2") && echo command A
(%when% mode1 "TYPE1 TYPE3") && echo command B
(%when% mode1 "TYPE3")       && echo command C

(%when% mode2 "TYPE1 TYPE2") && echo command X
(%when% mode2 "TYPE1 TYPE3") && echo command Y
(%when% mode2 "TYPE3")       && echo command Z
票数 2
EN

Stack Overflow用户

发布于 2014-06-11 14:53:03

我认为解决这个问题最清晰、最快的方法就是通过数组

代码语言:javascript
复制
@echo off
setlocal EnableDelayedExpansion

rem Define the array of equivalences from MODE values vs Command
set numCommands=0
for %%a in ("TYPE1|TYPE2=Command A"
            "TYPE1|TYPE3=Command B"
            "TYPE3=Command C") do (
   set /A numCommands+=1
   set "command[!numCommands!]=%%~a"
)

rem Get MODE as parameter:
set "MODE=%~1"

rem Execute the commands in order
for /L %%i in (1,1,%numCommands%) do (
   for /F "tokens=1,2 delims==" %%a in ("!command[%%i]!") do (
      set "options=|%%a|"
      if "!options:|%MODE%|=!" neq "!options!" ECHO Run: %%b
   )
)

编辑:或以更短的方式编辑,没有数组:

代码语言:javascript
复制
@echo off
setlocal EnableDelayedExpansion

set "MODE=%~1"

for %%i in ("TYPE1|TYPE2=Command A"
            "TYPE1|TYPE3=Command B"
            "TYPE3=Command C") do (
   for /F "tokens=1,2 delims==" %%a in (%%i) do (
      set "options=|%%a|"
      if "!options:|%MODE%|=!" neq "!options!" ECHO Run: %%b
   )
)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24160567

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档