0

This line works:

findstr /I /C:"Archiving file" "..\LogFiles\%NewLogFileName%"

Outputting the following to the screen:

2023-08-21 13:25:11.9024|Info|Archiving file

The next line I am looking for ERROR in a file. I know that ERROR is NOT in the file, so my expectation is that the error level should be 1, but it is continually 0.

findstr /I /C:"ERROR" "..\LogFiles\%NewLogFileName%"

IF ERRORLEVEL 1 (
     ECHO Error level AFTER Search %ERRORLEVEL%
)

What am I doing wrong?


Since this thread opened I have changed the code to:

findstr /I /C:"ERROR" "..\LogFiles\%NewLogFileName%"

call echo %%errorlevel%% & REM WORKS "1"

REM multiple iteration of these lines fail

REM Some things I have tried 
echo %errorlevel% & REM FAILS "0"

SET "somevar=%%errorlevel%%"

echo %somevar% & REM FAILS "0"

The text files are basic text. one has Archiving file in the contents the other DOES NOT HAVE error in the text.

What more can I provide?

Compo
  • 36,585
  • 5
  • 27
  • 39
Abby Normal
  • 41
  • 2
  • 7
  • Can't replicate - seems to work fine for me. – Stephan Aug 21 '23 at 18:00
  • Please cut the relevant section of the code and paste it into your question using the `edit` facility. Since `errorlevel` must be 1 or greater to display the `after search` message, I suspect that your code is within a block (parenthesised sequence of lines) and hence ot displays `errorlevel` as the value when the block was *parsed*. Try `call echo...%%errorlevel%%`. – Magoo Aug 21 '23 at 18:01
  • @Magoo call echo %%errorlevel%% works. But why the "Call" and "%%" ? I have tried Echo %ERRORLEVEL% right after the search, and it always returned zero...Thank you! – Abby Normal Aug 21 '23 at 18:32
  • @Stephan - what operating system? I am on Win 10 – Abby Normal Aug 21 '23 at 18:37
  • You didn't show relevant parts of your code (as Magoo guessed right). We need a reproducable problem to solve it. The answer to "why does this work" is [here](https://stackoverflow.com/questions/30282784/variables-are-not-behaving-as-expected/30284028#30284028) – Stephan Aug 21 '23 at 19:35
  • To be honest for the example you've shown, without a sample file content, I'd have used `find.exe`; either ```%SystemRoot%\System32\find.exe /I "ERROR" 0<"..\LogFiles\%NewLogFileName%"``` or for belt and braces, ```If Exist "..\LogFiles\%NewLogFileName%" (```, ```Type "..\LogFiles\%NewLogFileName%" | %SystemRoot%\System32\find.exe /I "ERROR"```, ```If ErrorLevel 1 Echo Errorlevel AFTER Search 1```, ```)```. However as is clear, and I'd also guessed, you posted an incomplete code snippet, which did not reflect the actual problem. That would be a delayed expansion issue! – Compo Aug 21 '23 at 19:37
  • @compo This is all there is..... What more can I provide? – Abby Normal Aug 21 '23 at 20:06
  • That in not technically true @AbbyNormal. I can say that because ```findstr /I /C:"ERROR" "..\LogFiles\%NewLogFileName%"``` would resolve to ```findstr /I /C:"ERROR" "..\LogFiles\"``` as you have not defined a variable named `NewLogFileName` anywhere in your code. Also by its very name, it is implied that other code exists too, otherwise this would not be a "New" Log File Name, if it existed before the batch file was invoked. Additionally without `Echo`ing `Off`, you'd have much more output that that which you showed before my latest edit. – Compo Aug 21 '23 at 21:22
  • Run in a command prompt window `%SystemRoot%\System32\where.exe findstr` exactly as written here (copy and paste the command line into the command prompt window). Is there output `C:\Windows\System32\findstr.exe`? Yes, that is good. What does happen on putting this command line into your batch with appending `& pause` to halt the batch file execution to see the output and running the batch file? Is there also output `C:\Windows\System32\findstr.exe`? Yes, then we know that at least the correct executable is run on using in the batch file just `findstr` instead of the fully qualified file name. – Mofi Aug 22 '23 at 06:37
  • The __FINDSTR__ argument `"..\LogFiles\%NewLogFileName%"` references the environment variable `NewLogFileName`. How is this environment variable defined in your batch file? What is the current directory on execution of the batch file? Does the batch file define the current working directory? I recommend reading [debugging a batch file](https://stackoverflow.com/a/42448601/3074564) which means removing `@echo off` from top of the batch file and running it from within a command prompt window instead of double clicking on the batch file. How does the command line look on execution? – Mofi Aug 22 '23 at 06:42
  • You might be interested also in [accessing the values of dynamic variables](https://stackoverflow.com/a/65979943/3074564). The first code posted by you should always work, except there is not executed `C:\Windows\System32\findstr.exe` on using just `findstr` in the batch file. It is advisable to use in a batch file always the fully qualified file name of a Windows command. Then `cmd.exe` does not need to search for the executable (faster) and it cannot happen running something completely different than expected making the batch file execution more fail-safe and secure. – Mofi Aug 22 '23 at 06:47

2 Answers2

0
findstr /ic:"error" "..\LogFiles\%NewLogFileName%" >nul && echo/0 || echo/1 

If your path/file exists or doesn't exist, if the string was found or not, forget errorlevel, use operators && return 0 and || return non 0.

Findstr /flag(s) <file.eXt && (do BC Return 0) || (do BC Return non 0)

FINDSTR will set %ERRORLEVEL% as follows:

    0 (False) a match is found in at least one line of at least one file.
    1 (True) if a match is not found in any line of any file, (or if the file is not found at all).
    2 Wrong syntax 
    
    An invalid switch will only print an error message in error stream;

@echo off 

command 1
command 2
command ...
command n
 
findstr /ic:"strings xy" <"..\Log\%New%" >nul && (
     command 1
     command 2
     command ...
     command n
     echo/0 
    ) || (
     command 1
     command 2
     command ...
     command n
     echo/1 
    )

command 1
command 2
command ...
command n


Additional resources:

Io-oI
  • 2,514
  • 3
  • 22
  • 29
0

As the batch langiage has evolved, the original line-by-line nature has been retained, but the concept of a "line" has changed to that of a "logical line".

Lines may now contain multiple commands separated by &. This has been extended to allow conditional execution by && and ||

Lines may be extended over multiple physical lines by using the line-continuation symbol ^ or by grouping commands within parentheses (know on SO as a block)

Since we sometimes need to use a character that is used as part of the language as a literal, we can "escape" the character (turn off the special meaning of the following character) by preceding it with a caret ^ - but the escape character for % is another %.

Quite how a logical line is executed is covered in this short article

Hence, when a logical line is parsed, any %var% found on the line is replaced by the value of that variable at that time - the time the line is parsed, before execution commences.

So the fragment call echo %%errorlevel%% is interpreted as call echo {escaped-%}errorlevel{escaped-%} and is executed in a sub-process as echo %errorlevel%.

Another approach is the use of delayed expansion

Magoo
  • 77,302
  • 8
  • 62
  • 84