为了清楚说明,我已经查看了有关此主题的其他问题,但是他们要么没有解决这个问题,要么更经常不解决它。
我怀疑问题与嵌套的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
答案 0 :(得分:1)
问题不在于SET的百分比扩张 这不会按预期工作,它会在解析块时扩展,而不是在执行时扩展 因此,您应该尝试延迟扩展。
答案 1 :(得分:0)
我学会了避免嵌套块并尽可能地写为短块。长或嵌套的块是调试的噩梦,并且块中的任何goto都会中断for
循环。所以我经常编写一个子程序call:subRoutine
,然后用goto:eof
返回。子例程以常规方式工作:可以更改变量并使用%variable%
访问它们。 {em> on 时Echo
写入命令的实际参数。 GoTo
也适用。您在调用另一个批处理文件时传递参数 - 子例程可以是单独的文件。然后call
之后没有冒号。
当然,仍然存在使用块方便且需要延迟扩展的情况。我想在这里表明还有另一种方式。