バッチ: サブルーチンで予期しない変数の結果が発生する

バッチ: サブルーチンで予期しない変数の結果が発生する

答え以前の質問この FOR 行を提案します。今、変数を使用しようとしています。現在の私のバッチ スクリプト:

@echo off
cls
for %%G in ("3D Objects","Documents","Downloads","Music","Pictures","Videos") do call :sub1 %%G
:sub1
echo %%G
set apath=%%~G
echo %apath%
goto :eof
:End

このスクリプトからの出力は、次の 7 回の繰り返しになります。

%G
%~G

サブルーチンは変数に対して何かを行っているようです。なぜなら、次の行を代入すると、

for %%G in ("3D Objects","Documents","Downloads","Music","Pictures","Videos") do (
echo %%G
set apath=%%~G
echo %apath%
)

望み通りの結果が得られました。次のような出力が 6 組得られました。

"3D Objects"
3D Objects

ここで、チルダは予想どおり引用符を削除します。

最初のコードサンプルでは、​​出力行のペアが7つ(6つではない)生成されていることから、サブルーチンが引用符を無視して「3D」と「オブジェクト」を2つの別々の項目としてレンダリングしている可能性があることがわかります。これは、前の質問

2 番目のコード サンプル (上記) で示したより単純なアプローチを使用して特定の結果を達成する際に問題があったため、サブルーチン アプローチをいじり始めました。遅延展開によってこの問題が解決される可能性がありますが、複雑さが増すという代償があります。サブルーチンの「goto :eof」行も、たとえ機能するとしても、少しわかりにくいことは否定できません。

私の具体的な質問は、サブルーチンで変数を使用すると何が問題になるのかということです。しかし、もっと良い方法があれば、少なくともその方向へのリンクもいただければ幸いです。

答え1

の値を渡していますのためにループ反復をサブルーチンに使用電話したがって、その (渡された変数のプレースホルダー) を二重引用符で囲み、そのサブルーチン内で渡された変数を として参照するか、%1囲ん%~1でいる二重引用符を削除します。

呼び出された各サブルーチンの最後にを使用すると、GOTO :EOF元の呼び出し元サブルーチンに制御が戻され、callコマンドの後に該当する場合は残りのロジックの処理を続行できます。

@echo off
cls
for %%G in ("3D Objects","Documents","Downloads","Music","Pictures","Videos") do call :sub1 "%%~G"
goto :eof

:sub1
echo %1
set apath=%~1
echo %apath%
goto :eof
:End

出力

"3D Objects"
3D Objects
"Documents"
Documents
"Downloads"
Downloads
"Music"
Music
"Pictures"
Pictures
"Videos"
Videos

サポートリソース

  • のために
  • コマンドライン引数(パラメータ)

    引数はサブルーチンに渡すこともできる。CALL:

    CALL :my_sub 2468

    コマンドライン上の数値位置の前に%を付けて引数の値を取得できます。渡される最初の項目は常に%1、2番目の項目は常に%2 %2、以下同様です。

    %*バッチ スクリプトでは、すべての引数を参照します (例: ) 。番号で参照できるのはへの%1 %2 %3 %4 %5 ...%255引数のみです。%1%9

  • 電話

    参照渡し

    コマンドラインで数値や文字列を渡すだけでなく、変数名前を付けて、その変数を使用してスクリプトまたはサブルーチン間でデータを転送します。参照渡しは少し高度な手法ですが、文字列に CMD 区切り文字または引用符が含まれている場合に特に便利です。


    サブルーチンを呼び出す (:label)

    このCALLコマンドは、指定されたラベルと指定されたパラメータの後のステートメントに制御を渡します。サブルーチンを終了するには、GOTO :eof現在のサブルーチンの最後に制御を移すように指定します。

  • CALL /?

    CALL command now accepts labels as the target of the CALL.  The syntax
    is:
    
        CALL :label arguments
    
    
    In addition, expansion of batch script argument references (%0, %1,
    etc.) have been changed as follows:
    
    
        %* in a batch script refers to all the arguments (e.g. %1 %2 %3
            %4 %5 ...)
    
        Substitution of batch parameters (%n) has been enhanced.  You can
        now use the following optional syntax:
    
            %~1         - expands %1 removing any surrounding quotes (")
    

関連情報