Pedro Sales
Pedro Sales

Reputation: 553

batch file with echo findstr not working inside for loop

I have multiple string that come from a reg query inside a for loop. I want to validate for each of them if it has certain words and do actions if it has. My code is this:

for /l %%g in (0 1 3) do (
        echo HOME%%g
        for /f "tokens=1,2,3*" %%h in ('reg query \\%%c\HKLM\SOFTWARE\ORACLE\HOME%%g /v ORACLE_HOME') do (

            echo HOME%%g
            echo %%j
            echo %%j | findstr /I /R /C:"806"
            if %ERRORLEVEL% equ 0 (
                echo YES
            ) else (
                echo NO
            )

            echo %%j | findstr /C:".isuites."
            if %ERRORLEVEL% equ 0 (
                echo YES
            ) else (
                echo NO
            )

            echo %%j | findstr /I ora90
            if errorlevel 0 (
                echo YES
            ) else (
                echo NO
            )

            echo %%j | findstr /I forms10
            if errorlevel 0 (
                echo YES
            ) else (
                echo NO
            )



        )
    )

The problem is that is does not validates the string as seen in the output

HOME0
HOME0
ECHO is off.
YES
YES
YES
YES
HOME0
d:\oracle\806
d:\oracle\806
YES
YES
YES
YES
HOME1
HOME1
ECHO is off. 
YES
YES
YES
YES
HOME1
d:\oracle\iSuites
YES
YES
YES
YES
HOME2
HOME2
ECHO is off.
YES
YES
YES
YES
HOME2
d:\oracle\ora90
YES
YES
d:\oracle\ora90
YES
YES
HOME3
HOME3
ECHO is off.
YES
YES
YES
YES
HOME3
D:\oracle\forms10g
YES
YES
YES
D:\oracle\forms10g
YES

Upvotes: 0

Views: 2192

Answers (1)

MC ND
MC ND

Reputation: 70923

Some corrections are needed in your code

Change for %%h into

for /f "tokens=1,2,*" %%h in ('reg query \\%%c\HKLM\SOFTWARE\ORACLE\HOME%%g /v ORACLE_HOME ^| find "REG_SZ" ') do ( 

That way, the ORACLE_HOME key name will be in %%h, the REG_SZ type in %%i and the folder in %%j (i supose this is what you intended)

With this done, the next problem is errorlevel checks

When a block of code (code inside parenthesis) is parsed, all variable reads are replaced with the value inside the variable before starting to execute the block. So, if you use %errorlevel% inside you block of code, as this variable read has been replaced with the value of the variable before starting to execute, you will not see the real value.

You can use delayed expansion (include setlocal enabledelayedexpansion at the start of batch file) and change the syntax from %errorlevel% to !errorlevel! to indicate to the parser that the variable read should be delayed until the moment the command is executed.

Or you can use the if errorlevel n ... syntax. In this case you should remember that the condition will be true for any errorlevel value greater or equal than the indicated value.

That is, if errorlevel is 1, both if errorlevel 1 and if errorlevel 0 will be true. For this reason, the proper way of checking error level is to check from greater values to lower values

echo %%j | findstr .....
if errorlevel 1 (
    ...
) else (
    ...
)

So, your code should be something like

....
....
for /l %%g in (0 1 3) do (
        echo Testing HOME%%g
        echo ---------------------------------
        for /f "tokens=1,2,*" %%h in (
            'reg query \\%%c\HKLM\SOFTWARE\ORACLE\HOME%%g /v ORACLE_HOME 2^>nul ^| find "REG_SZ" '
        ) do (

            echo %%j | findstr /L /C:"806"
            if errorlevel 1 (
                echo NO
            ) else (
                echo YES
            )

            echo %%j | findstr /C:".isuites."
            if errorlevel 1 (
                echo NO
            ) else (
                echo YES
            )

            echo %%j | findstr /I /C:"ora90" 
            if errorlevel 1 (
                echo NO
            ) else (
                echo YES
            )

            echo %%j | findstr /I /C:"forms10"
            if errorlevel 1 (
                echo NO
            ) else (
                echo YES
            )

        )
    )
)

edited to adapt to comments

Some of the HOMEn will not be echoed if they does not exist in registry. To "solve" it, the error output from req query is included in the data to be parsed and it is tested if the string ERROR: is found.

for /l %%g in (0 1 3) do (
        echo Testing HOME%%g
        echo ---------------------------------
        for /f "tokens=1,2,*" %%h in (
            'reg query \\%%c\HKLM\SOFTWARE\ORACLE\HOME%%g /v ORACLE_HOME 2^>^&1 ^| findstr /L /C:"REG_SZ" /C:"REG_EXPAND_SZ" /C:"ERROR:" '
        ) do (
            for %%z in ("806" ".isuites." "ora90" "forms10") do (
                (if "%%h"=="ERROR:" (echo() else (echo %%j)) | findstr /i /c:"%%~z"
                if errorlevel 1 (
                    echo NO
                ) else (
                    echo YES
                )
            )
        )
    )
)

Upvotes: 2

Related Questions