2016-11-18 13 views
0

以下に示すようなコマンドライン引数の配列に対してループが実行されるものとします。 次に、次のコマンドライン値をループ内の変数に割り当てるにはどうすればよいですか? Linuxではバッチスクリプトで変数に変数を動的に割り当てる方法は?

FOR %%q IN (%*) DO 
(
IF %%q == "abc" (
set a = //next command line value 
      ) 
) 

これは、私はバッチファイルで、この同等のものを知りたい

argv=("[email protected]"); 
i=0 
while(($i < ${#argv[*]})); do 
case "${argv[$i]}" in 
abc) 
    ((i++)); a="${argv[$i]}" 
;; 
esac 
((i++)) 
done 

のように行うことができます。

+1

'/ fヘルプ 'と'遅延拡張'を確認してください – npocmaka

+0

バッチ(シェルスクリプト)を使用しないでください。 PowerShellははるかに優れています。 –

答えて

0

状態変数を使用します。

setlocal 
rem Undefine state variable first, in case it's defined somewhere else. 
set is_abc= 
for %%q in (%*) DO (
    if defined is_abc (
     set a=%%q 
     set is_abc= 
    ) else (
     if "%%q" == "abc" set is_abc=1 
    ) 
) 
1

私は引数を読むためにfor-loopを使用しません。 LinuxDiscipleに記載されているように、バッチをbashやcshとあまりにも速く比較しないでください。たとえば。配列やハッシュをバッチで作成したりアクセスしたりするのは簡単ではありません(興味がある場合は、答えの最後にリンクを追加して、どのようにできるかを説明します)。 forループを実際に使用したい場合は、おそらく状態変数の使用が最適です(Klitos Kyriacou's answer参照)。

私は、変数を割り当てるとき、それは(と変数名を予期しない結果を与える可能性があり、スペースで「=」囲まない、代わりにLinuxDiscipleもmentionned

@echo off 
SetLocal EnableDelayedExpansion 
:check_args 
REM Check if arguments left 
IF "%~1%" == "" goto :EndArgs 
IF "%~1" == "abc" (
    REM next argument is %2 
    set var=%~2 
    REM Don't forget extra shift because you already handled next argument too 
    shift 
    echo I just saw you gave "abc", I set var to !var! 
) ELSE (
    echo It's just a normal argument: "%~1" 
) 
shift 
goto :check_args 

:EndArgs 
EndLocal 
exit 

としてバッチで、伝統的なラベルとgoto文を使用します末尾のスペース、見出しスペースの値、...)。上記のコードは、(スクリプトがargum.batと呼ばれている)ようなものになります。ここでは

>argum abc blabla def 
I just saw you gave "abc", I set var to "blabla" 
It's just a normal argument: def 

>argum "just random things" abc "this is more serious" 
It's just a normal argument: "just random things" 
I just saw you gave "abc", I set var to "this is more serious" 

delayed expansionへのリンクです。この場合、cmd-parserはIF-clauseとFOR-loopを1つのコマンドとして読み込みます(1行に書かれているかのように)。遅延拡張を使用しない限り、同じコマンドで変数を作成して読み込むことはできません。また、%var%の代わりに!var!を使用する理由も説明します。 は私も周囲の引用符( ")を削除するには%~1の代わり%1を使用あなたには、いくつかのより多くをしたい場合は、

オフコース引数とforループ変数を操作するために使用できる『トリック。このlinkは、いくつかの他のを持っています』あなたの議論を複雑なものにすることは、if-else節のサイズのために良い選択肢ではありません。私がこれを尋ねたときに使ったようなあなたの議論を扱うためには、別の方法を使わなければなりません。回答も同様)またはこのquestionの回答として提案されている方法(私の質問にも回答としてリンクされています)

幸運!

PSバッチ内のアレイソリューションへのpromissed、リンクとして:それはもう一つの方法は、内のすべての要素をリストアップすることで、通常の配列インデックス

  • を使用するように、「トリッキー」である理由this tutorial

    • あなたが表示されます文字列を区切り文字で区切ります(空白は大部分が使用されます)。区切り文字を区切り文字として(あなたの行ったように)反復するためにfor /f - loopを使います。ここでの問題は、反復中に他の配列要素にアクセスするために余分な変数を使用する必要があることです。
  • 0

    J. Baobyの解と同様に、この解はループまたは状態変数を使用しません。このソリューションはまた、遅延拡張や局所的局所性を必要としません。
    もっと多くの引数の処理を追加するのは簡単です。ネストされたIFはありません。
    これは、 "-a"の前の値と "-b"の前にある値を解析します。他の引数は、後で必要になる場合があるので、otherArgsという変数に別々に格納します。

    @ECHO OFF 
    REM make sure we don't start with unintended values 
    set avar= 
    set bvar= 
    set otherArgs= 
    :loop 
    REM Exit the loop when we run out of input 
    if "%1" == "" goto outsideOfLoop 
    
    REM ==Check for an argument which is preceded by '-a'=============== 
    if "%1"=="-a" set avar=%2 & shift /1 & shift /1 & goto :loop 
    REM ==END '-a' handling here======================================== 
    
    REM ==Check for an argument which is preceded by '-b'=============== 
    if "%1"=="-b" set bvar=%2 & shift /1 & shift /1 & goto :loop 
    REM ==END -'b' handling here======================================== 
    
    REM default case here 
    set otherArgs=%otherArgs% %1 
    shift /1 
    goto :loop 
    :outsideOfLoop 
    echo.%%avar%% is %avar% 
    echo.%%bvar%% is %bvar% 
    echo.Other arguments were: %otherArgs% 
    

    出力:

    C:\Users\me>junk.bat hi there def -b BValue ef -a aValue valuebc 123 456 
    %avar% is aValue 
    %bvar% is BValue 
    Other arguments were: hi there def ef valuebc 123 456 
    

    これは、%I引数を消費するの副作用を持っていますが、それは中にネストされたif文の増え続けるの深さを必要としません。より多くの議論を処理するために、あなたが処理した引数を別の引数から分離します。後でそれらを処理する必要がある場合は、すでに認識した引数を削除する必要はありません。

    関連する問題