2013-08-24 3 views
23

Ich frage mich, ob es eine einfache Möglichkeit gibt, die Ausführung in einer Windows-Batch-Datei abhängig von dem Wert eines einzelnen Ausdrucks verzweigen. Ähnlich wie Wechsel/Case-Blöcke in C, C++, C#, Java, Javascript, PHP und anderen realen Programmiersprachen.Switch-Anweisung entspricht in Windows-Batch-Datei

Meine einzige Lösung ist eine einfache if/else Block, in dem der gleiche Ausdruck wiederholt auf Gleichheit mit unterschiedlichen Werten geprüft:

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

So stumm. Jede bessere Lösung?

+2

Eine andere Möglichkeit (obwohl ich zusammenzucken, um Goto vorzuschlagen!) .... Sie können Label ': ID1'': ID2' usw. erstellen, und eine 'Goto ID% ID%' sollte zum entsprechenden springen. Aber die Art, wie du es schon machst, ist nicht so schrecklich, oder? Ich bin mir sicher, dass es andere Sprachen gibt, in denen der gesamte Ausdruck auf jedem Fall/jeder Schalterlinie steht. –

+0

Beachten Sie, dass in vielen Sprachen, die eine 'switch'-Anweisung haben (dies gilt für C und C++ zumindest), dieses Konstrukt für Geschwindigkeitsoptimierungszwecke verwendet wird, da es den wiederholten Vergleich der if-else-if-Kette vermeidet. Das kann teuer sein. Gewöhnlich gibt es in diesem Fall keine ** große ** Lesbarkeitsgewinne bei Verwendung von "switch", da die verketteten Vergleiche nicht so hässlich sind (man vergleicht nur mit einer Konstanten). Ich hoffe, dass Ihre Frage durch Neugierde ausgelöst wird und Sie nicht wirklich eine Batch-Datei optimieren möchten! :-) ;-) –

+0

@LorenzoDonati Ich beschwere mich nicht über die Lesbarkeit des 'IF' /' ELSE' Konstrukts (wer kam auf Lesbarkeit?). Ich denke nur, dass es nicht schlau und fehleranfällig ist, ähnlichen Code mehrmals zu schreiben. Und nein, mach dir keine Sorgen ... Geschwindigkeit ist auch kein Problem :-) Ich bin nur neugierig, weil ich bei der Codierung von Batch-Skripten oft auf diese Art von Problemen gestoßen bin. –

Antwort

49

Für jeden, der immer noch auf diese Frage stieß, benutzte ich Etikettennamen, die die Werte für die Case-Ausdrücke enthielten, wie von AjV Jsy vorgeschlagen. Wie auch immer, ich verwende CALL anstelle von GOTO, um in den richtigen Fallblock zu springen und GOTO :EOF, um zurückzuspringen. Der folgende Beispielcode ist ein vollständiges Stapelscript, das die Idee veranschaulicht.

@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

kreativ, aber ziemlich bösen Code –

10

Dies ist einfacher zu lesen. Wenn es nicht zu dem passt, was Sie tun müssen, dann beschreiben Sie es besser.

+1

Danke! Lesbarkeit ist immer gut, aber ich frage mich, ob es möglich ist zu vermeiden, den Vergleichsausdruck zu wiederholen (hier "IF"% ID% "== ...'). –

+1

Berechnungen können verwendet werden - sie hängen jedoch von der genauen Aufgabe ab. Batch-Dateien sind meistens auf den genauen Anforderungen einer Aufgabe aufgebaut und deshalb können sehr wenige Batch-Dateien in jeder Situation ohne Modifikation verwendet werden. – foxidrive

2

Ich suchte switch/case heute Batch-Dateien und stolperte diese auf. Ich habe diese Lösung verwendet und sie um eine goto exit erweitert.

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

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

:exit 

, die in den Grundzustand (Echo Linie) und keine zusätzlichen if ‚s bringt, wenn die Wahl zu finden ist.

1

Versuchen Sie auf diese Weise. So führen Sie eine Liste von Operationen wie

  1. Switch Gehäuse wurde verwendet.
  2. Überprüfen der bedingten Anweisungen.
  3. Aufrufen der Funktion mit mehr als zwei Argumenten.

@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

Compact Form für kurze Befehle (kein 'Echo'):

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

Nach^sofort Zeilenende sein müssen, keine Leerzeichen

0

ich denke, alle anderen Optionen wäre kryptischer. Für diejenigen, die lesbar und nicht-kryptischen Code mag:

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

Es ist wie eine Anekdote:

Magician: Legen Sie das Ei unter dem Hut, tun die Magie passiert ... Nehmen Sie den Hut und. .. das gleiche Ei bekommen, aber in der Seitenansicht ...

die IFELSE Lösung ist nicht so schlimm. Es ist fast so gut wie Pythons ifelifelse. Mehr kryptische "Eier" können here gefunden werden.

2

Es könnte ein bisschen spät, aber das tut es:

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

setlocal EnableDelayedExpansion 
!%switch%! 
endlocal 

% Schalter% vor Zeile ersetzt wird Ausführung. Schwerwiegende Nachteile:

  • außer Kraft setzen Sie den Fall Variablen
  • Es braucht DelayedExpansion

schließlich nützlich sein könnte in einigen Fällen.