47

我想知道是否有一种简单的方法可以根据单个表达式的值在 Windows 批处理文件中分支执行。类似于 C、C++、C#、Java、JavaScript、PHP 和其他真实编程语言中的 switch/case 块。

我唯一的解决方法是一个普通的 if/else 块,其中重复检查相同的表达式是否与不同的值相等:

IF "%ID%"=="0" (
  REM do something
) ELSE IF "%ID%"=="1" (
  REM do something else
) ELSE IF "%ID%"=="2" (
  REM do another thing
) ELSE (
  REM default case...
)

如此愚蠢。有更好的解决方案吗?

4

9 回答 9

72

我最终使用了包含 AjV Jsy 建议的 case 表达式值的标签名称。无论如何,我使用CALL而不是GOTO跳入正确的案例块并GOTO :EOF跳回。以下示例代码是一个完整的批处理脚本,说明了这个想法。

@ECHO OFF

SET /P COLOR="Choose a background color (type red, blue or black): "

2>NUL CALL :CASE_%COLOR% # jump to :CASE_red, :CASE_blue, etc.
IF ERRORLEVEL 1 CALL :DEFAULT_CASE # If label doesn't exist

ECHO Done.
EXIT /B

:CASE_red
  COLOR CF
  GOTO END_CASE
:CASE_blue
  COLOR 9F
  GOTO END_CASE
:CASE_black
  COLOR 0F
  GOTO END_CASE
:DEFAULT_CASE
  ECHO Unknown color "%COLOR%"
  GOTO END_CASE
:END_CASE
  VER > NUL # reset ERRORLEVEL
  GOTO :EOF # return from CALL
于 2013-11-05T18:03:10.607 回答
18

这更容易阅读:

IF "%ID%"=="0" REM do something
IF "%ID%"=="1" REM do something else
IF "%ID%"=="2" REM do another thing
IF %ID% GTR 2  REM default case...
于 2013-08-25T03:41:26.677 回答
8

短命令的紧凑形式(没有“回声”):

IF "%ID%"=="0" ( ... & ... & ... ) ELSE ^
IF "%ID%"=="1" ( ... ) ELSE ^
IF "%ID%"=="2" ( ... ) ELSE ^
REM default case...

After^必须是立即行结束,不能有空格。

于 2017-12-28T16:53:16.303 回答
6

我想所有其他选项都会更加神秘。对于那些喜欢可读和非神秘代码的人:

IF        "%ID%"=="0" (
    REM do something

) ELSE IF "%ID%"=="1" (
    REM do something else

) ELSE IF "%ID%"=="2" (
    REM do another thing

) ELSE (
    REM default case...
)

这就像一个轶事:

魔术师:把鸡蛋放在帽子下面,做魔法通行证……取下帽子,然后……得到同一个鸡蛋,但在侧视图中……

IF ELSE解决方案还不错。它几乎和 python 的一样好if elif else。更多神秘的“鸡蛋”可以在这里找到。

于 2018-01-12T07:23:50.530 回答
2

switch / case今天在批处理文件中搜索并偶然发现了这一点。我使用了这个解决方案并用goto exit.

IF "%1"=="red" echo "one selected" & goto exit
IF "%1"=="two" echo "two selected" & goto exit
...

echo "Options: [one | two | ...]

:exit 

当找到选择时,它会带来默认状态(回声线)并且没有额外if的 's。

于 2016-07-17T09:25:50.797 回答
2

Hariprasad didupe 提出了 Batchography 提供的解决方案,但可以稍微改进一下。与其他情况不同,进入默认情况会将 ERRORLEVEL 设置为 1,如果不需要,您应该手动将 ERRORLEVEL 设置为 0:

goto :switch-case-N-%N% 2>nul || (
    rem Default case
    rem Manually set ERRORLEVEL to 0 
    type nul>nul
    echo Something else
)
...

以开销为代价可以提高可读性call

call:Switch SwitchLabel %N% || (
:SwitchLabel-1
    echo One
    goto:EOF     
:SwitchLabel-2
    echo Two
    goto:EOF
:SwitchLabel-3
    echo Three
    goto:EOF
:SwitchLabel-
    echo Default case
)

:Switch
goto:%1-%2 2>nul || (
    type nul>nul
    goto:%1-
)
exit /b

有几点需要注意:

  1. 如前所述,这有call开销;
  2. 需要默认大小写。如果不需要任何操作,则放入rem其中以避免括号错误;
  3. 除默认情况外的所有情况都在子上下文中执行。如果你想退出父上下文(通常是脚本),你可以使用这个
  4. 默认案例在父上下文中执行,因此不能与其他案例组合(因为到达goto:EOF将退出父上下文)。这可以通过goto:%1-在子程序中替换call:%1-为以额外call开销为代价来规避;
  5. 子程序采用标签前缀(无连字符)和控制变量。没有标签前缀开关将寻找带有:-前缀的标签(有效)并且不传递控制变量将导致默认情况。
于 2019-09-25T09:16:37.560 回答
1

试试这个方法。执行一些操作列表,例如

  1. 开关盒已使用。
  2. 检查条件语句。
  3. 使用两个以上的参数调用函数。

 @echo off
 :Start2 
    cls
    goto Start
    :Start
    echo --------------------------------------
    echo     Welcome to the Shortcut tool     
    echo --------------------------------------            
    echo Choose from the list given below:
    echo [1] 2017
    echo [2] 2018
    echo [3] Task

    set /a one=1
    set /a two=2
    set /a three=3
    set /a four=4
    set input=
    set /p input= Enter your choice:
    if %input% equ %one% goto Z if NOT goto Start2
    if %input% equ %two% goto X if NOT goto Start2
    if %input% equ %three% goto C if NOT goto Start2
    if %input% geq %four% goto N

    :Z
    cls
    echo You have selected year : 2017
    set year=2017
    echo %year%
    call:branches year

    pause
    exit

    :X
    cls
    echo You have selected year : 2018
    set year=2018
    echo %year%
    call:branches year
    pause
    exit

    :C  
    cls
    echo You have selected Task
    call:Task
    pause
    exit

    :N
    cls
    echo Invalid Selection! Try again
    pause
    goto :start2




    :branches
    cls
    echo Choose from the list of Branches given below:
    echo [1] January
    echo [2] Feburary
    echo [3] March
    SETLOCAL
    set /a "Number1=%~1"
    set input=
    set /p input= Enter your choice:
    set /a b=0
    set /a bd=3
    set /a bdd=4
    if %input% equ %b% goto N
    if %input% leq %bd% call:Z1 Number1,input if NOT goto Start2
    if %input% geq %bdd% goto N



    :Z1
    cls
    SETLOCAL
    set /a "Number1=%~1"
    echo year = %Number1%
    set /a "Number2=%~2"
    echo branch = %Number2%
    call:operation Number1,Number2
    pause
    GOTO :EOF


    :operation
    cls
    echo Choose from the list of Operation given below:
    echo [1] UB
    echo [3] B
    echo [4] C
    echo [5] l
    echo [6] R
    echo [7] JT
    echo [8] CT
    echo [9] JT
    SETLOCAL
    set /a "year=%~1"
    echo Your have selected year = %year%
    set /a "month=%~2"
    echo You have selected Branch = %month%
    set operation=
    set /p operation= Enter your choice:
    set /a b=0
    set /a bd=9
    set /a bdd=10
    if %input% equ %b% goto N
    if %operation% leq %bd% goto :switch-case-N-%operation% if NOT goto Start2
    if %input% geq %bdd% goto N




    :switch-case-N-1
    echo Januray
    echo %year%,%month%,%operation%
    goto :switch-case-end

    :switch-case-N-2
    echo Feburary
    echo %year%,%month%,%operation%
    goto :switch-case-end

    :switch-case-N-3
    echo march
    echo %year%,%month%,%operation%
    goto :switch-case-end

    :switch-case-end
       echo Task Completed
       pause
       exit
       goto :start2






    :Task
    cls
    echo Choose from the list of Operation given below:
    echo [1] UB
    echo [3] B
    echo [4] C
    echo [5] l
    echo [6] R
    echo [7] JT
    echo [8] CT
    echo [9] JT
    SETLOCAL
    set operation=
    set /p operation= Enter your choice:
    set /a b=0
    set /a bd=9
    set /a bdd=10
    if %input% equ %b% goto N
    if %operation% leq %bd% goto :switch-case-N-%operation% if NOT goto Start2
    if %input% geq %bdd% goto N




    :switch-case-N-1
    echo Januray
    echo %operation%
    goto :switch-case-end

    :switch-case-N-2
    echo Feburary
    echo %year%,%month%,%operation%
    goto :switch-case-end

    :switch-case-N-3
    echo march
    echo %year%,%month%,%operation%
    goto :switch-case-end

    :switch-case-end
       echo Task Completed
       pause
       exit
       goto :start2
于 2017-10-22T11:52:24.447 回答
1

如果if不工作,你使用:

:switch case %n%=1 
statements;
goto :switch case end
etc..

http://lallouslab.net/2016/12/21/batchography-switch-case/

于 2018-01-31T01:20:07.423 回答
1

可能有点晚了,但是这样做:

set "case1=operation1"
set "case2=operation2"
set "case3=operation3"

setlocal EnableDelayedExpansion
!%switch%!
endlocal

%switch% 在行执行之前被替换。严重的缺点:

  • 您覆盖案例变量
  • 它需要延迟扩展

在某些情况下最终可能有用。

于 2018-02-16T11:04:40.943 回答