1

これを明確にするために、この件に関する他の質問を見てきましたが、この問題に対処していないか、多くの場合、修正していません。

問題は、入れ子になった FOR ループと、SETLOCAL を配置する場所に関係していると思われます。

私が持っているのは、特定の時間以降にファイルが変更されたことを確認する機能です。

:CheckCopied result directory filename since -- returns whether the file has been modified in the time since 'since'
::                      -- result    [out]    - 0=FAIL, 1=SUCCESS
::                      -- directory [in]     - target directory
::                      -- filename [in]      - target filename
::                      -- since [in]         - the time the script started
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
set directory=%~2
set filename=%~3
set since=%~4

ECHO.CheckCopied directory="%directory%", filename=%filename%, since=%since%

FOR /F "tokens=1,2 delims= " %%d IN ('echo ^| dir "%directory%" ^| find "%filename%"') DO  (
    FOR /F "tokens=1,2 delims=:" %%h IN ('echo %%e') DO (
        ECHO Hours:  %since:~0,2%  vs  %%h
        ECHO Minutes:  %since:~3,2%  vs  %%i
        SET hours=!since:~0,2!
        SET minutes=%since:~3,2%
        ECHO hours=%hours%   minutes=%minutes%
        SET /A minutesSince=60*hours+minutes
        ECHO %minutesSince%
        SET hours=%%h
        SET minutes=%%i
        ECHO hours=%hours%   minutes=%minutes%
    )
)

EXIT /b

これは以下を出力します:

CheckCopied directory="<my directory>" filename=<my filename> since=15:18:34.98
Hours:  15  vs  15
Minutes:  18  vs  11
hours=  minutes=
ECHO is off.
hours=  minutes=

したがって、「SET hours=!since:~0,2!」動作しないようです。

私が試してみました:

SET hours=!since:~0,2!
SET hours=%since:~0,2%
SET /A hours=!since:~0,2!
Every combination I could think of of SETLOCAL ENABLEDELAYEDEXPANSION and ENDLOCAL

私はそれがSETLOCALと関係があると仮定していますが、魔法の組み合わせが見つかりません...

編集:

以下のjebに感謝します。ここで彼のアドバイスに従って機能をやり直しました:

:CheckCopied result directory filename since -- returns whether the file has been modified in the last 5 minutes
::                      -- result    [out]    - 0=FAIL, 1=SUCCESS
::                      -- directory [in]     - target directory
::                      -- filename [in]      - target filename
::                      -- since [in]         - the time the script started
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
set directory=%~2
set filename=%~3
set since=%~4

ECHO.CheckCopied directory="%directory%", filename=%filename%, since=%since%

FOR /F "tokens=1,2 delims= " %%d IN ('echo ^| dir "%directory%" ^| find "%filename%"') DO (
    FOR /F "tokens=1,2 delims=:" %%h IN ('echo %%e') DO (
        ECHO Hours:  %since:~0,2%  vs  %%h
        ECHO Minutes:  %since:~3,2%  vs  %%i
        SET hours=!since:~0,2!
        SET minutes=!since:~3,2!
        ECHO hours=!hours!   minutes=!minutes!
        SET /A minutesSince=60*hours+minutes
        ECHO !minutesSince!
        SET /A hoursx=%%h
        SET /A minutesx=%%i
        ECHO hours=!hoursx!   minutes=!minutesx!
        SET /A minutesSincex=60*hoursx+minutesx
        ECHO !minutesSincex!
    )
)
ENDLOCAL

EXIT /b

要約すると、予想されるものと必要なものは次のとおりです。

SET hours=%since:~0,2%  ==> SET hours=!since:~0,2!
ECHO hours=%hours%      ==> ECHO hours=!hours!
SET hoursx=%%h          ==> SET /A hoursx=%%h
4

2 に答える 2

1

問題は、SETの拡張率ではありません。
これは期待どおりに機能しません。ブロックが実行されるときではなく、解析されるときに拡張されます。
したがって、遅延拡張を試す必要があります。

于 2012-06-26T14:44:15.117 に答える
0

ネストされたブロックを避け、できるだけ短いブロックを書くことを学びました。長いブロックや入れ子になったブロックはデバッグするのに悪夢であり、ブロック内の goto はforループを壊します。そのため、私はしばしばサブルーチンを書き、call:subRoutineそこから で戻りgoto:eofます。サブルーチンは通常の方法で動作します: 変数を変更し、%variable%. Echoonの場合、コマンドの実パラメータを書き込みます。GoTo同様に動作します。別のバッチ ファイルを呼び出すようにパラメーターを渡します。サブルーチンは別のファイルにすることもできます。.の後にコロンはありませんcall

もちろん、ブロックの使用が便利で、delayedExpansion が必要な場合もあります。ここでは、別の方法があることを示したかっただけです。

于 2018-02-09T10:07:39.240 に答える