Batch file. How to use FindStr with percentages

I have a batch file with the following header:

@Echo off
SETLOCAL EnableDelayedExpansion EnableExtensions

      

Inside If

a parenthesized statement , ()

I have the following code:

Echo SOME_VAR|FindStr /r /C:"^.*SOME.*$"
Echo Error: !errorlevel!
Echo %%SOME_VAR%%|FindStr /r /C:"^.*SOME.*$"
Echo Error: !errorlevel!

      

This will print:

SOME_VAR
Error: 0
Error: 1

      

If SOME_VAR is an existing environment variable, this is what I get. If I remove the variable, I get the expected success.

What's going on here? Do I need to avoid something more? How can I get a successful find on the second one if the variable exists? I am only interested in a text search where the searched text contains a character %

and it matches an existing variable name.

By the way, the source for the comparison will eventually also be the variable in which I loaded the PATH as read from the windows registry. So in the end the line I'm looking for will become/C:"^.%%SOME_VAR%%;.*$"

My PATH variable looks like this:

%SOME_VAR%;C:\Windows\system32...................etc

      

+3


source to share


1 answer


Yes, a different level of escape is required because each side of the pipe is executed through CMD /C

with a command line context, not a batch context. The initial parser-parser converts %%SOME_VAR%%

to %SOME_VAR%

. The command line parser then leaves %SOME_VAR%

as if the variable was undefined. We need to prevent expansion if the variable is defined. Doubling percent does not work in the context of the command line. The solution is to insert a vanishing caret somewhere between percentages, for example %^SOME_VAR%

. The caret is treated as part of the variable name, so it prevents the variable from expanding (unless you have a variable named^SOME_VAR

). After unsuccessful expansion, the carriage is consumed by the normal evacuation process. The caret must be escaped so that the batch parser will pass the caret to the command line context CMD /C

.

Final batch line:

Echo %%^^SOME_VAR%% | FindStr SOME_VAR

      

Note. I have simplified the FINDSTR command into a much simpler but equivalent search.

When you change the search to the right to include percentages, you will also need to insert an escaped caret.



Update in response to a question in a comment
The following code demonstrates some possible ways of working with variables:

@echo off
setlocal disableDelayedExpansion

:: Put both the text you want to search, as well as the search itself, in variables
set "text=%%SOME_VAR%%;C:\Windows\system32...................etc"
set "search=%%SOME_VAR%%"
echo text=%text%
echo search=%search%
echo(

echo(
echo Starting with delayed expansion disabled
echo -----------------------------------------
echo(

:: Use delayed expansion to safely expand any variable without worrying about content.
:: Both sides of the pipe are executed in a command line context with delayed expansion disabled.
:: You must use CMD /V:ON to enable delayed expansion within the pipe.

echo Test when SOME_VAR is undefined:
set "SOME_VAR="
if 1==1 (
  cmd /v:on /c echo !text!|cmd /v:on /c findstr "!search!"
)
echo(

echo Test when SOME_VAR is defined:
set "SOME_VAR=DEFINED"
if 1==1 (
  cmd /v:on /c echo !text!|cmd /v:on /c findstr "!search!"
)
echo(


setlocal enableDelayedExpansion
echo(
echo(
echo Now try with delayed expansion enabled
echo -----------------------------------------
echo(

:: Even though delayed expansion is enabled within the batch script, it is still disabled
:: within the pipe, so we still have to explicitly enable it via CMD /V:ON.
:: But now we must prevent expansion of the variables while in the batch context.
:: You have two options:

:: 1) Escape the !. The escape syntax changes depending on whether it is inside quotes or not:
echo Escape test:
if 1==1 (
  cmd /v:on /c echo ^^!text^^!|cmd /v:on /c findstr "^!search^!"
)
echo(

:: 2) Enclose both sides of the pipe within parentheses (very weird, but it works)
echo Parentheses test:
if 1==1 (
  (cmd /v:on /c echo !text!)|(cmd /v:on /c findstr "!search!")
)

      

- OUTPUT -

text=%SOME_VAR%;C:\Windows\system32...................etc
search=%SOME_VAR%


Starting with delayed expansion disabled
-----------------------------------------

Test when SOME_VAR is undefined:
%SOME_VAR%;C:\Windows\system32...................etc

Test when SOME_VAR is defined:
%SOME_VAR%;C:\Windows\system32...................etc



Now try with delayed expansion enabled
-----------------------------------------

Escape test:
%SOME_VAR%;C:\Windows\system32...................etc

Parentheses test:
%SOME_VAR%;C:\Windows\system32...................etc

      

+3


source







All Articles