Dea*_*ean 2 for-loop batch-file
我正在尝试创建一个循环,它将通过指定目录中的一组文本文件搜索字符串.根据是否找到字符串报告结果.但是%errorlevel%
始终返回0并且计算结果为0.
SETLOCAL enabledelayedexpansion
FOR %%G IN (*.txt) DO (
find /i "My text string" "%%G"
ECHO %date% %time% : errorlevel is %errorlevel% >> %report_dir%\%computername%.txt
IF %errorlevel% EQU 1 (
ECHO %date% %time% : String found >> %report_dir%\%computername%.txt
GOTO:copy_log
)
)
ENDLOCAL
Run Code Online (Sandbox Code Playgroud)
雷蒙德你的意思是?:
SETLOCAL enabledelayedexpansion
FOR %%G IN (*.txt) DO (
find /i "My text string" "%%G"
IF %errorlevel% (
ECHO %date% %time% : String found >> %report_dir%\%computername%.txt
GOTO:copy_log
)
)
ENDLOCAL
Run Code Online (Sandbox Code Playgroud)
%ERRORLEVEL%
正在迅速扩大.您可以通过以下方式完全避免此问题:
IF ERRORLEVEL 1
Run Code Online (Sandbox Code Playgroud)
或者有关详细信息,请参阅SET /?
帮助文本中对"延迟环境变量扩展"的说明:
最后,增加了对延迟环境变量扩展的支持.默认情况下,此支持始终处于禁用状态,但可以通过
/V
命令行切换到CMD.EXE 来启用/禁用此支持.看到CMD /?
延迟环境变量扩展对于解决当读取文本行时发生的当前扩展的限制很有用,而不是在执行时.以下示例演示了立即变量扩展的问题:
Run Code Online (Sandbox Code Playgroud)set VAR=before if "%VAR%" == "before" ( set VAR=after if "%VAR%" == "after" @echo If you see this, it worked )
永远不会显示消息,因为
%VAR%
在读取第一个IF语句时会替换BOTH IF语句,因为它在逻辑上包含IF的主体,这是一个复合语句.因此,复合语句中的IF实际上是在比较"之前"和"之后",它永远不会相等.同样,以下示例将无法按预期工作:Run Code Online (Sandbox Code Playgroud)set LIST= for %i in (*) do set LIST=%LIST% %i echo %LIST%
因为它不会在当前目录中建立文件列表,而只是将LIST变量设置为找到的最后一个文件.同样,这是因为%LIST%在读取FOR语句时只展开一次,并且此时LIST变量为空.所以我们正在执行的实际FOR循环是:
Run Code Online (Sandbox Code Playgroud)for %i in (*) do set LIST= %i
只是将LIST设置为找到的最后一个文件.
延迟环境变量扩展允许您使用不同的字符(感叹号)在执行时扩展环境变量.如果启用了延迟变量扩展,则可以按如下方式编写上述示例以按预期工作:
Run Code Online (Sandbox Code Playgroud)set VAR=before if "%VAR%" == "before" ( set VAR=after if "!VAR!" == "after" @echo If you see this, it worked )
同样,这是因为%LIST%在读取FOR语句时只展开一次,并且此时LIST变量为空.所以我们正在执行的实际FOR循环是:
Run Code Online (Sandbox Code Playgroud)for %i in (*) do set LIST= %i
只是将LIST设置为找到的最后一个文件.
延迟环境变量扩展允许您使用不同的字符(感叹号)在执行时扩展环境变量.如果启用了延迟变量扩展,则可以按如下方式编写上述示例以按预期工作:
Run Code Online (Sandbox Code Playgroud)set VAR=before if "%VAR%" == "before" ( set VAR=after if "!VAR!" == "after" @echo If you see this, it worked ) set LIST= for %i in (*) do set LIST=!LIST! %i echo %LIST%
我更喜欢让For
循环调用分支。它可以防止变量扩展问题:
For %%G In (*.txt) Do Call :ScanFile "%%G"
Exit /B
:ScanFile
Find /i "My text string" "%~1"
If %ErrorLevel%==1 (
Echo %date% %time% : String found >> %report_dir%\%computername%.txt
Goto :CopyLog
)
Exit /B
:CopyLog
...
Exit /B
Run Code Online (Sandbox Code Playgroud)