2011-08-21 163 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 \卸載