我做了这个代码
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%
有任何想法吗?
我做了这个代码
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%
有任何想法吗?
在 for 循环和括号范围内设置和使用变量有两种方法。
setlocal enabledelayedexpansion
见setlocal /?
寻求帮助。这仅适用于 XP/2000 或更新版本的 Windows。然后在循环内使用!variable!
而不是...%variable%
使用批处理 goto labels 创建批处理函数: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
批处理函数是非常有用的机制。
你可能想要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
。
我为此奋斗了好几个小时。这是我注册命令行变量的循环。示例:Register.bat /param1:value1 /param2:value2
它的作用是循环所有命令行参数,并将具有正确名称的变量设置为值。
之后,您可以使用 set value=!param1! 设置 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
使用 %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
代码评论:
进一步阅读
使用以下链接更详细地确定原因:
为了扩展答案,我来到这里以获得更好的理解,所以我写了这个可以解释它并帮助我。
它setlocal DisableDelayedExpansion
在里面有,所以你可以在setlocal EnableDelayedExpansion
它和它之间根据需要在本地设置它。
@echo off
title %~nx0
for /f "tokens=*" %%A in ("Some Thing") do (
setlocal EnableDelayedExpansion
set z=%%A
echo !z! Echoing the assigned variable in setlocal scope.
echo %%A Echoing the variable in local scope.
setlocal DisableDelayedExpansion
echo !z! &rem !z! Neither of these now work, which makes sense.
echo %z% &rem ECHO is off. Neither of these now work, which makes sense.
echo %%A Echoing the variable in its local scope, will always work.
)
set list = a1-2019 a3-2018 a4-2017
setlocal enabledelayedexpansion
set backup=
set bb1=
for /d %%d in (%list%) do (
set td=%%d
set x=!td!
set y=!td!
set y=!y:~-4!
if !y! gtr !bb1! (
set bb1=!y!
set backup=!x!
)
)
rem: backup will be 2019
echo %backup%
如果您访问范围之外的变量,则可以使用宏
@echo off
::Define macro
set "sset=set"
for /l %%a in (1,1,4) do (
::set in loop
%sset% /a "x[%%a]=%%a*%%a"
if %%a equ 4 (
:: set in condition
%sset% "x[%%a]=x Condition"
%sset% "y=y Condition"
)
)
echo x1=%x[1]% x2=%x[2]% x3=%x[3]% x4=%x[4]% y=%y%
:: Bonus. enableDelayedExpansion used to access massive from the loop
setlocal enableDelayedExpansion
echo Echo from the loop
for /l %%a in (1,1,4) do (
::echo in one line - echo|set /p =
echo|set /p "=x%%a=!x[%%a]! "
if %%a equ 4 echo y=%y%
)
pause
尝试这个:
setlocal EnableDelayedExpansion
...
for /F "tokens=*" %%a in ('type %FileName%') do (
set z=%%a
echo !z!
echo %%a
)
我知道这不是所要求的,但是当我尝试在“循环”中设置变量时,我从这种方法中受益。使用数组。替代实施选项。
SETLOCAL ENABLEDELAYEDEXPANSION
...
set Services[0]=SERVICE1
set Services[1]=SERVICE2
set Services[2]=SERVICE3
set "i=0"
:ServicesLoop
if defined Services[%i%] (
set SERVICE=!Services[%i%]!
echo CurrentService: !SERVICE!
set /a "i+=1"
GOTO :ServicesLoop
)
以下应该有效:
setlocal EnableDelayedExpansion
for /F "tokens=*" %%a in ('type %FileName%') do (
set "z=%%a"
echo %z%
echo %%a
)