2013-08-24 5 views
23

Mi chiedo se esiste un modo semplice per eseguire l'esecuzione in un file batch di Windows in base al valore di una singola espressione. Qualcosa simile a switch/case block in C, C++, C#, Java, Javascript, PHP e altri linguaggi di programmazione reali.equivalente in file batch di Windows

La mia unica soluzione è una pianura se/blocco else in cui la stessa espressione viene ripetutamente controllato per l'uguaglianza contro valori diversi:

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... 
) 

così stupido. Qualche soluzione migliore?

+2

Un altro modo (anche se mi viene da suggerire Goto!) .... è possibile creare etichette ': ID1': ID2' ecc. Ma il modo in cui lo stai già facendo non è poi così terribile, vero? Sono sicuro che ci sono altri linguaggi in cui l'intera espressione si trova su ogni caso/linea di commutazione. –

+0

Ricordare che in molte lingue è presente un'istruzione 'switch' (questo è vero per C e C++) che il costrutto viene utilizzato per scopi di ottimizzazione della velocità, poiché evita il confronto ripetuto della catena if-else-if, che può essere costoso. Di solito non esiste un ** grande ** guadagno di leggibilità nell'uso di 'switch' in questo caso, poiché i confronti concatenati non sono così brutti (basta confrontare una costante). Spero che la tua domanda sia motivata dalla curiosità e che tu non voglia veramente ottimizzare la velocità di un file batch! :-) ;-) –

+0

@LorenzoDonati Non mi sto lamentando della leggibilità del costrutto 'IF' /' ELSE' (che è apparso leggibile?). Penso solo che non sia intelligente ed incline agli errori a scrivere codice simile più volte. E no, non ti preoccupare ... anche la velocità non è una preoccupazione :-) Sono solo curioso perché ho incontrato questo tipo di problemi molte volte durante la codifica degli script batch. –

risposta

49

Per chiunque ancora colpire su questa domanda, ho finito per usare i nomi delle etichette contenenti i valori per il caso espressioni come suggerito da AJV Jsy. Ad ogni modo, io uso CALL invece di GOTO per saltare nel blocco del caso corretto e GOTO :EOF per tornare indietro. Il seguente codice di esempio è uno script batch completo che illustra l'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 
+2

codice creativo, ma piuttosto cattivo –

10

Questo è più semplice da leggere. Se non soddisfa ciò che devi fare, descriverlo meglio.

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... 
+1

Grazie! La leggibilità è sempre buona, ma mi chiedo se è possibile evitare di ripetere l'espressione di confronto (qui 'IF"% ID% "== ...'). –

+1

I calcoli possono essere utilizzati, ma dipenderanno dal compito esatto. I file batch sono spesso costruiti sui requisiti esatti di un'attività e questo è il motivo per cui pochissimi file batch possono essere utilizzati in qualsiasi situazione senza modifiche. – foxidrive

2

Ho cercato switch/case in file batch oggi e siamo capitati per questo. Ho usato questa soluzione e l'ho estesa con un goto exit.

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

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

:exit 

che porta in stato di default (linea di eco) e non in più if 's quando viene trovata la scelta.

1

Provare in questo modo. Per eseguire un elenco di operazioni come

  1. È stata utilizzata la custodia dell'interruttore.
  2. Controllo delle istruzioni condizionali.
  3. Invocazione della funzione con più di due argomenti.

@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 
1

forma compatta per comandi brevi (no 'echo'):

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

Dopo^deve essere fine linea immediato, senza spazi

0

credo che tutte le altre opzioni sarebbe più criptico Per coloro che amano il codice leggibile e non criptico:

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... 
) 

E 'come un aneddoto:

Mago: Mettere l'uovo sotto il cappello, fare la magia passa ... Rimuovere il cappello e. .. ottenere lo stesso uovo, ma nella vista laterale ...

la soluzione IFELSE non è così male. È quasi buono come lo if python elifelse. Altre "uova" enigmatiche possono essere trovate here.

2

Potrebbe essere un po 'in ritardo, ma questo lo fa: Interruttore

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

setlocal EnableDelayedExpansion 
!%switch%! 
endlocal 

%% viene sostituito prima linea esecuzione. aspetti negativi gravi:

  • di ignorare le variabili caso
  • Si deve DelayedExpansion

potrebbe eventualmente essere utile in alcuni casi.