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

我学会了避免嵌套块并尽可能编写短块。长块或嵌套块是调试和块中断for循环中的任何 goto 的噩梦。所以我经常写一个子程序,并call:subRoutine从它返回goto:eof。该子例程以常规方式工作:可以更改变量并使用%variable%. Echo,当on时,写入命令的实际参数。GoTo也可以。您像调用另一个批处理文件一样传递参数 - 子例程可以是单独的文件。然后 . 后面没有冒号call

当然,仍然存在使用块很方便并且需要延迟扩展的情况。我想在这里只是为了表明还有另一种方式。

于 2018-02-09T10:07:39.240 回答