2016-10-22 14 views
1

私は自分のバッチファイルを書き込んで、npmのバージョンを(ちょうど楽しみのために)切り替えようとしています。バッチファイルでネストされた変数の抽象化を使用するにはどうすればよいですか?

@echo off 
for /f "delims=" %%i in ('npm -v') do set output=%%i 
move "%NPM_PATH%" "%NPM_PATH%-%output%" 

FOR %%A IN (%*) DO (
    IF "%%A"=="--change" (
    SETLOCAL EnableDelayedExpansion 

    SET /A c=1 
    ECHO "ID : VERSION" 
    ECHO ------------------------- 

    FOR /F "tokens=*" %%F in ('dir /on /b /a:d /p "%NPM_DIR%"') DO ( 
     ECHO !c! : %%F 
     SET dir_!c!=%%F 
     SET /a c=c+1 
    ) 

    set /p id="enter version ID: (e.g. !dir_1! enter 1):" 
    set target_dir= "dir_!id!" 
    echo !target_dir! 
) 
) 

抽象化したい正しい変数をエコーアウトできます。

しかし、実際に!target_dir!の値を出力するにはどうすればよいですか?

例:

ユーザが画面にdir_1を印刷する1

echo !target_dir!を選択します。

しかし、私は次のecho !dir_1!を使用すると、npm-4.0.0が印刷されます。

ユーザーが1を入力したときに、どのように出力するのですか?npm-4.0.0

+0

変更この行: '設定をtarget_dir ='これにより、 "dir_ ID!": 'call set target_dir =" %% dir_!id!%% "'またはこれを以下に示します: 'for %% i in(!id!)do set target_dir ="!dir _ %% i! "';第2のものが好ましいものである。 [この質問](http://stackoverflow.com/questions/40096886/how-to-use-delayed-variable-expansion-to-reference-a-variable-from-a-string/)を参照してください。 – Aacini

+0

これは私の質問に対する答えです。 – TheRealMrCrowley

+0

私はスペースを削除しなければならなかったが、%% iのための '%!i(!id!)do set target_dir =!dir _ %% i!' – TheRealMrCrowley

答えて

0

私はちょうどこの行を変更するために必要な@Aaciniを1として:このいずれかにset target_dir= "dir_!id!"を::for %%i in (!id!) do set target_dir=!dir_%%i!

See this question

1

私は、コードや他のいくつかの改善に使用されるAaciniによって提供される第二の提案で次のコードを使用することをお勧め:for %%I in (!id!) do set "TargetDir=!dir_%%I!"が入力した番号であることXで名前dir_Xで環境変数の値を代入するのはなぜ

@echo off 
for /F "delims=" %%I in ('npm.bat -v') do set "output=%%I" 
move "%NPM_PATH%" "%NPM_PATH%-%output%" 

for %%A in (%*) do (
    if "%%A" == "--change" (
     setlocal EnableDelayedExpansion 
     cls 
     set "Count=1" 
     echo ID : VERSION 
     echo ------------------------- 

     for /F "tokens=*" %%F in ('dir /A:D /B /ON "%NPM_DIR%"') do (
      if !Count! LSS 10 (
       echo !Count! : %%F 
      ) else (
       echo !Count! : %%F 
      ) 
      set "dir_!Count!=%%F" 
      set /A Count+=1 
     ) 

     echo. 
     set "id=1" 
     set /P "id=Enter version ID: (e.g. !dir_1! enter 1): " 
     for %%I in (!id!) do set "TargetDir=!dir_%%I!" 
     echo !TargetDir! 
     endlocal 
    ) 
) 

を環境変数idに格納されている詳細は、Aacini'sの回答Arrays, linked lists and other data structures in cmd.exe (batch) scriptで詳細に説明されています。適用改善のため

は参照:

環境変数割り当ての等号の周りの空間とどの程度である

それはCamelCase表記で自己説明する名前を持つ環境変数を使用してお勧めします。これは、変数が何であるかを知る利点があり、変数のすべての出現を簡単に検索することができます。名前がcの変数を検索するのは少し難しく、多くの文字列では1文字が頻繁に発生するためです。

オプション/Aのコマンドsetは、次のすべてが算術式と解釈されることを意味します。これは、等号の後の文字列がスペース/タブを文字列セパレータとして使用して文字列のリストに分割されることを意味します。 10進数、8進数、または16進数として解釈される各文字列は、32ビットの符号付き整数に変換されます。演算子でない他の文字列はすべて、値を32ビット符号付き整数に変換する必要がある変数の名前として解釈されます。変数が存在しないか、値として数値を持たない場合は、変数に0が使用されます。次に、算術式が評価され、結果が整数から文字列に変換されます。最後に結果文字列は、等号に残された環境変数に割り当てられます。だから、と多くの追加作業が行われたのはSET "c=1"ですが、結果は同じですが、値1の文字列が変数cに割り当てられています。そのため、環境変数に値を代入する際に/Aを使用しないことをお勧めします。文字列が実際には数値であるかどうかのプリミティブチェックのような理由があります。注:set /A c=009のような割り当てでは、009が無効な8進数で、cが定義されていないか、またはすでに定義されている場合には現在の値を保持するため、エラーメッセージが表示されます(set c=009)。

バッチユーザーが文字列の入力を求められた場合、ユーザーは単にRETURNまたは、まったく何も入力せずにをENTERをヒットする自由を持っています。この場合、環境変数は現在の値を保持するか、またはユーザーにプロンプ​​トを出す前に定義されていなければまだ定義されていません。これは、ユーザにプロンプ​​トを表示する前に上記のバッチコードでset "id=1"が存在する理由を説明しています。ユーザーが実際に数字を入力したかどうか、また数字が1 ... !Count!の場合はチェックされませんが、入力ミスが常に発生する可能性がありますが、これは本当に必要ではないかもしれません。

+0

を引用してください。なぜelseと全く同じものを2つ実行するif文を書くのですか?それはちょうど意味がありません – TheRealMrCrowley

+0

と私はそれがintであることを指定する方法は、 "余分な仕事がたくさんある"違いのための場面の裏に行ってバリデーター以上のことはできません – TheRealMrCrowley

+0

2つの__echo__コマンドライン2つの__IF__ブランチは同じではありません。それらを注意深く見てください。 1スペースの違いがあります。カウント値が10より小さいTRUEブランチは、番号と先頭のスペースを含むディレクトリ名を出力します。カウント値が10以上のFALSEブランチは、先行スペースのない数値を出力します。結果は '1'〜' 99'の 'ID'の下の右揃えの数字です。まあ、 '%NPM_DIR%'と一致するディレクトリの数が常に10未満の場合、IF条件は本当に役に立たず、TRUEブランチの__echo__行が本当に必要です。 – Mofi

関連する問題