2011-08-21 24 views
2

我想要做一个循环,将通过搜索字符串的指定目录中的一组文本文件。根据是否找到字符串来报告结果。但%errorlevel%总是返回0,计算结果为0。批处理%errorlevel%在FOR循环中返回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 

雷蒙德做你的意思是?:

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 
+1

如文档中提到,您使用感叹号的延迟扩展和百分比立即扩张的迹象。你仍然在使用'%ERRORLEVEL%',它会立即被扩展。你想延迟,所以你需要'!ERRORLEVEL!'。或者你可以通过说'IF ERRORLEVEL 1'来避免整个问题。 –

回答

4

我宁愿让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 
+0

这是最简单的解决方案。谢谢。 – Dean

8

%ERRORLEVEL%被过早地扩大。您只需避免问题完全由使用:

IF ERRORLEVEL 1 

或进一步详情,请参阅“延迟环境变量扩充”从SET /?帮助文本这样的解释:

最后,支持对于延迟环境变量扩展已添加 。默认情况下,此支持始终处于禁用状态,但可能通过/V命令行切换到CMD.EXE启用/禁用 。见CMD /?

延迟环境变量扩充是获取当前扩大而不是在执行它恰好在 一行文本阅读,围绕 局限性有用。下面的示例 显示了与即时变量扩展问题:

set VAR=before 
    if "%VAR%" == "before" (
     set VAR=after 
     if "%VAR%" == "after" @echo If you see this, it worked 
    ) 

绝不会显示该消息,因为在这两种IF语句 是取代的IF语句被读取时,第一%VAR%,因为它在逻辑上 包括主体的IF,这是一个复合陈述。因此,复合陈述中的IF 确实比较“之前”与 “之后”,这将永远不会相等。同样,预计下面的例子 将不起作用:

set LIST= 
    for %i in (*) do set LIST=%LIST% %i 
    echo %LIST% 
的是,它不会建立文件列表在当前目录下,

而是将只设置LIST变量找到的最后一个文件。 同样,这是因为当读取FOR 语句时,%LIST%仅展开一次,并且此时LIST变量为空。所以 ,我们真正执行的循环是:

for %i in (*) do set LIST= %i 

这个循环继续将LIST到找到的最后一个文件。

延迟的环境变量扩展允许您使用不同的 字符(感叹号)来扩展环境变量,执行时间为 。如果延迟变量扩充被启用,如预期上述 例子可以写成如下工作:

set VAR=before 
    if "%VAR%" == "before" (
     set VAR=after 
     if "!VAR!" == "after" @echo If you see this, it worked 
    ) 

再次,这是因为%LIST%扩大只是一次当FOR 声明被读取,那时LIST变量是空的。所以 ,我们真正执行的循环是:

for %i in (*) do set LIST= %i 

这个循环继续将LIST到找到的最后一个文件。

延迟的环境变量扩展允许您使用不同的 字符(感叹号)来扩展环境变量,执行时间为 。如果延迟变量扩充被启用,如预期上述 例子可以写成如下工作:

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% 
2

正如雷蒙说,你正在评估%ERRORLEVEL%的回声,它几乎总是(永远说永不)返回沿下面的线为0

的事情会做的更好:

FOR %%G IN (*.txt) DO (
    find /i "My text string" "%%G" 
    SET error = %errorlevel% 
    ECHO %date% %time% : errorlevel is %errorl% >> %report_dir%\%computername%.txt 
    IF %error% EQU 1 (
     ECHO %date% %time% : String found >> %report_dir%\%computername%.txt 
     GOTO:copy_log 
    ) 
) 
0

我在通过注册表项/值进行循环时遇到了同样的问题,并且来到这篇文章。我的“reg查询”在for循环中总是有ERRORLEVEL 0。

这里是我的解决方案:

for %%s in (%ToBeUninstalled%) do ( REG QUERY "%KEY64%\%%s" | find /i "UninstallString" > NUL && (msiexec.exe /x %%s /qb) || (echo Software not installed) )

KEY64是HKLM \ SOFTWARE \ Wow6432Node \微软\的Windows \ CurrentVersion \卸载