2013-03-12 18 views
5

このループは、外部ファイルのすべての行について繰り返します。私は、これは動作しませんが、すべてのパスで選択肢のためのユーザーを促したいと思います。私は、GOTOコマンドを使ってループを何とか壊してしまうという問題があると思います。これについての考えは?FORループの選択 - Windowsバッチ

FOR /F %%i IN (%WORKDIR%\grunt-packages.ini) DO (
    CHOICE /C AN /M "Odinstalovat plugin" 
    IF %ERRORLEVEL%==1 GOTO UNINSTALL 
    IF %ERRORLEVEL%==2 GOTO SKIP 

    :UNINSTALL 
     ECHO Odstranuji %%i 
     CALL npm uninstall %%i 

    :SKIP 
     ECHO Preskakuji %%i 
) 

答えて

8

あなたの計算は正しいです。 forループ内のgotoはループを停止します。これを回避する方法は、代わりにcallを使用することです。しかし、スクリプトの最初の問題は、変数ERRORLEVELの遅延拡張の必要性です。カッコの範囲内に設定されている変数を展開するときは、遅延拡張を使用して最新の値を取得します。

SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION 
FOR /F %%i IN (%WORKDIR%\grunt-packages.ini) DO (
    CHOICE /C AN /M "Odinstalovat plugin" 
    IF !ERRORLEVEL!==1 CALL :UNINSTALL 
    IF !ERRORLEVEL!==2 CALL :SKIP 
) 
ENDLOCAL 
GOTO :EOF 

:UNINSTALL 
    ECHO Odstranuji %%i 
    CALL npm uninstall %%i 
    GOTO :EOF 

:SKIP 
    ECHO Preskakuji %%i 
    GOTO :EOF 
  1. gotoforループ内で使用することができません。
  2. カッコ内に設定された変数は、新しい値を取得するために遅延拡張が必要です。 %の代わりに!です。それ以外の場合は、カッコのスコープの前の変数の値が使用されます。
+0

の使用を避け、ありがとうございました! – Ozrix

+0

+1ですが、別の回答も掲載しました。 – jimhark

5

@メッツァーの答えは良いスタートだった(私はそれを投票した)が、いくつかの問題を見つけた。最後に、私はコードをインラインにして、CALLsを避ける方が好きです。ここに私のテストコードはどのように行うのを示すためにです:

@echo off 
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION 
FOR %%i IN (A B C D) DO (
    CHOICE /C AN /M "Uninstall plugin %%i" 
    IF !ERRORLEVEL!==1 (
     ECHO Uninstall %%i 
    ) ELSE IF !ERRORLEVEL!==2 (
     ECHO Skip %%i 
    ) 
) 

私は、Windows XP上のメッツガーの答え@テストし、以下の問題が見つかりました:Windows XP上GOTO :EOF(すでに固定)

  • を逃す

    • サブルーチン、サブルーチンに%%iは、アンインストールがERRORLEVELを設定した場合、SKIPが
    01と呼ばれるかもしれない
  • (潜在的なバグ)設定されていません

    このテストコードは、問題が修正されています。

    @echo off 
    SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION 
    FOR %%i IN (A B C D) DO (
        CHOICE /C AN /M "Uninstall plugin %%i" 
        SET OERRORLEVEL=!ERRORLEVEL! 
        IF !ERRORLEVEL!==1 CALL :UNINSTALL %%i 
        IF !OERRORLEVEL!==2 CALL :SKIP %%i 
    ) 
    ENDLOCAL 
    GOTO :EOF 
    
    :UNINSTALL 
        ECHO Uninstall %1 
        GOTO :EOF 
    
    :SKIP 
        ECHO Skip %1 
        GOTO :EOF 
    
  • +0

    +1これは注意すべきポイントです。 ** ':)' **特に、UNINSTALLにERRORLEVELが設定されている可能性があります。私はパラメータとして '%% i'を渡すことについて言及したと考えましたが、それが必要ではないと考えました(7と8のままで動作します)。 –

    +0

    upvoted、thanksありがとう – Ozrix

    1

    この構造は、華麗なDELAYEDEXPANSION

    @ECHO OFF 
    SETLOCAL 
    FOR %%i IN (A B C D) DO (
    SET destcall=BADCHOICE 
    choice /c QJ /M "%%i - choose Q or J" 
    IF ERRORLEVEL 1 SET destcall=CHOSEQ 
    IF ERRORLEVEL 2 SET destcall=CHOSEJ 
    CALL CALL :%%destcall%% 
    ) 
    GOTO :eof 
    
    :badchoice 
    ECHO bad choice 
    GOTO :eof 
    
    :choseq 
    ECHO You chose Q 
    GOTO :eof 
    
    :chosej 
    ECHO You chose J 
    GOTO :eof 
    
    関連する問題