68

このコードを作りました

dir /B /S %RepToRead% > %FileName%

for /F "tokens=*" %%a in ('type %FileName%') do (
    set z=%%a
    echo %z%
    echo %%a
)

echo %%a正常に動作していますが、 echo %z%「エコー無効」が返されます。

のように変数を分割したいので、 %z% を設定する必要があります%z:~7%

何か案は?

4

10 に答える 10

92

for ループと括弧のスコープ内で変数を設定および使用するには、2 つの方法があります。

  1. setlocal enabledelayedexpansionを参照setlocal /?してください。これは、XP/2000 以降のバージョンの Windows でのみ機能します。次に、ループ内の!variable!代わりに使用します...%variable%

  2. バッチ goto ラベルを使用してバッチ関数を作成します:Label

    例:

    for /F "tokens=*" %%a in ('type %FileName%') do call :Foo %%a
    goto End
    
    :Foo
    set z=%1
    echo %z%
    echo %1
    goto :eof
    
    :End
    

    バッチ関数は非常に便利なメカニズムです。

于 2012-12-10T21:47:52.097 に答える
55

あなたはおそらくしたいですSETLOCAL ENABLEDELAYEDEXPANSION。詳細については、 https://devblogs.microsoft.com/oldnewthing/20060823-00/?p=29993を参照してください。

基本的には、ノーマルはコマンドを読み込んだ%variables%直後に展開されます。cmd.exeあなたの場合、「コマンド」は全体です

for /F "tokens=*" %%a in ('type %FileName%') do (
    set z=%%a
    echo %z%
    echo %%a
)

ループ。その時点でzは にはまだ値がないため、 にecho %z%変わりますecho。次に、ループが実行されてz設定されますが、その値は使用されなくなります。

SETLOCAL ENABLEDELAYEDEXPANSION追加の構文を有効にします!variable!。これも変数を展開しますが、各 (サブ) コマンドが実行される直前にのみ展開します。

SETLOCAL ENABLEDELAYEDEXPANSION
for /F "tokens=*" %%a in ('type %FileName%') do (
    set z=%%a
    echo !z!
    echo %%a
)

これによりz、実行するたびに現在の値が得られますecho

于 2012-12-10T16:54:30.197 に答える
12

私はこれに何時間も苦労しました。これは、コマンドライン変数を登録するための私のループです。例 : Register.bat /param1:value1 /param2:value2

すべてのコマンドラインパラメーターをループし、適切な名前の変数を値に設定します。

その後、 set value=!param1! を使用できます。set value2=!param2!

パラメータが与えられた順序に関係なく。(いわゆる名前付きパラメーター)。%<>% の代わりに !<>! に注意してください。

SETLOCAL ENABLEDELAYEDEXPANSION

FOR %%P IN (%*) DO (
    call :processParam %%P
)

goto:End

:processParam [%1 - param]

    @echo "processparam : %1"
    FOR /F "tokens=1,2 delims=:" %%G IN ("%1") DO (
        @echo a,b %%G %%H
        set nameWithSlash=%%G
        set name=!nameWithSlash:~1!
        @echo n=!name!
        set value=%%H
        set !name!=!value!
    )
    goto :eof

:End    
于 2014-11-23T20:35:14.563 に答える
3

%var%、!var!、および %% を使用したバッチ コードの簡単な例。

このコード例では、組み込み変数 TIME を使用して開始時間を取得することに重点を置いています (時間は常に自動的に変更されるため、時間を使用しています)。

コード:

@echo off
setlocal enabledelayedexpansion
SET "SERVICES_LIST=MMS ARSM MMS2"
SET START=%TIME%
SET "LAST_SERVICE="

for %%A in (%SERVICES_LIST%) do (
    SET START=!TIME!
    CALL :SOME_FUNCTION %%A
    SET "LAST_SERVICE=%%A"
    ping -n 5 127.0.0.1 > NUL
    SET OTHER=!START!
    if !OTHER! EQU !START! (
    echo !OTHER! is equal to !START! as expected
    ) ELSE (
    echo NOTHING
    )
)
ECHO Last service run was %LAST_SERVICE%

:: Function declared like this
:SOME_FUNCTION
echo Running: %1
EXIT /B 0

コードに関するコメント:

  • 有効な遅延展開を使用する
  • 最初の 3 つの SET 行は、SET コマンドの一般的な使用法であり、ほとんどの場合これを使用します。
  • 次の行は for ループです。反復には %%A を使用し、その中のループの場合は %%B を使用する必要があります。長い変数名は使用できません。
  • 時間変数などの変更された変数にアクセスするには、!! を使用する必要があります。または !! で設定 (有効な遅延拡張が有効になっています)。
  • for ループでループする場合、各反復は %%A 変数としてアクセスされます。
  • for ループのコードは、変数を設定するさまざまな方法を示しています。'SET OTHER=!START!' を見ると、SET OTHER=%START% に変更した場合、その理由がわかります!! が必要です。(ヒント: 何も表示されません) 出力。
  • 要するに !!ループ内で必要になる可能性が高く、通常は %var%、%% は常に for ループです。

参考文献

次のリンクを使用して、詳細な理由を確認してください。

于 2020-04-30T16:32:00.860 に答える