Switch statement equivalent in Windows batch file

前端 未结 9 1047
無奈伤痛
無奈伤痛 2020-12-03 00:40

I wonder if there is a simple way to branch execution in a Windows batch file depending on the value of one single expression. Something akin to switch/case blocks in C, C++

相关标签:
9条回答
  • 2020-12-03 01:29

    This is simpler to read:

    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...
    
    0 讨论(0)
  • 2020-12-03 01:30

    I ended up using label names containing the values for the case expressions as suggested by AjV Jsy. Anyway, I use CALL instead of GOTO to jump into the correct case block and GOTO :EOF to jump back. The following sample code is a complete batch script illustrating the idea.

    @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
    
    0 讨论(0)
  • 2020-12-03 01:33

    Hariprasad didupe suggested a solution provided by Batchography, but it could be improved a bit. Unlike with other cases getting into default case will set ERRORLEVEL to 1 and, if that is not desired, you should manually set ERRORLEVEL to 0:

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

    The readability could be improved for the price of a call overhead:

    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
    

    Few things to note:

    1. As stated before, this has a call overhead;
    2. Default case is required. If no action is needed put rem inside to avoid parenthesis error;
    3. All cases except the default one are executed in the sub-context. If you want to exit parent context (usually script) you may use this;
    4. Default case is executed in a parent context, so it cannot be combined with other cases (as reaching goto:EOF will exit parent context). This could be circumvented by replacing goto:%1- in subroutine with call:%1- for the price of additional call overhead;
    5. Subroutine takes label prefix (sans hyphen) and control variable. Without label prefix switch will look for labels with :- prefix (which are valid) and not passing a control variable will lead to default case.
    0 讨论(0)
提交回复
热议问题