17

I need to find out if a certain environment variable (let's say Foo) contains a substring (let's say BAR) in a windows batch file. Is there any way to do this using only batch file commands and/or programs/commands installed by default with windows?

For example:

set Foo=Some string;something BAR something;blah

if "BAR" in %Foo% goto FoundIt     <- What should this line be? 

echo Did not find BAR.
exit 1

:FoundIt
echo Found BAR!
exit 0

What should the marked line above be to make this simple batch file print "Found BAR"?

Joey
  • 330,812
  • 81
  • 665
  • 668
LCC
  • 1,130
  • 1
  • 17
  • 26

3 Answers3

31

Of course, just use good old findstr:

echo.%Foo%|findstr /C:"BAR" >nul 2>&1 && echo Found || echo Not found.

Instead of echoing you can also branch elsewhere there, but I think if you need multiple statements based on that the following is easier:

echo.%Foo%|findstr /C:"BAR" >nul 2>&1
if not errorlevel 1 (
   echo Found
) else (
    echo Not found.
)

Edit: Take note of jeb's solution as well which is more succinct, although it needs an additional mental step to figure out what it does when reading.

Community
  • 1
  • 1
Joey
  • 330,812
  • 81
  • 665
  • 668
  • Your solution works if the `%Foo%` variable contains a semi-colon `;`, like the `%PATH%` variable. You can also throw a `/I` to findstr to make the search case insensitive. You can also search for the content of another variable by replacing `BAR` with `%SEARCH_TERM%`. Quite usefull! – ixe013 Jun 30 '17 at 01:10
26

The findstr solution works, it's a little bit slow and in my opinion with findstr you break a butterfly on a wheel.

A simple string replace should also work

if "%foo%"=="%foo:bar=%" (
    echo Not Found
) ELSE (
    echo found
)

Or with inverse logic

if NOT "%foo%"=="%foo:bar=%" echo FOUND

If both sides of the comparision are not equal, then there must be the text inside the variable, so the search text is removed.

A small sample how the line will be expanded

set foo=John goes to the bar.
if NOT "John goes to the bar."=="John goes to the ." echo FOUND
jeb
  • 74,839
  • 15
  • 166
  • 215
  • +1. Yes, I'm a bit unhappy with findstr at times due to performance as well (particularly noticeable in my bignum lib which checks numbers for correct format several times during computations – that quickly adds up). Didn't think of that solution. – Joey Mar 30 '11 at 20:50
  • Random stuff: We both have problems with an unmatched quote in the haystack, though. – Joey Mar 30 '11 at 20:59
  • 1
    @Joey: If quotes are possible in the content, delayed expansion should be the solution – jeb Mar 30 '11 at 21:02
  • Can anyone explain the seemingly backwards logic behind `if not %var% == %var:str=%` and how it returns true when you ARE looking for `str` in `%var%`? I can't quite make sense of it. – mythofechelon Jan 07 '13 at 16:53
  • Tried this solution with PATH but not working. http://stackoverflow.com/questions/38695620/windows-check-string-contains-another-not-working – Billa Aug 01 '16 at 10:45
  • @Billa It fails, as your question is different. You try to check if the content of a variable is part of the content of another variable – jeb Aug 01 '16 at 12:46
  • I tried other possible solutions. But none of them worked for me. Tried `findstr /m "D:\Package\Libraries\Lib" %PATH% if %errorlevel%==1 add env path` – Billa Aug 01 '16 at 15:44
  • This might help explain https://stackoverflow.com/questions/7005951/batch-file-find-if-substring-is-in-string-not-in-a-file/25539569 – dgxhubbard Jun 11 '19 at 17:01
2

I wrote this function for a nice script integration. Code looks better and it's also easier to remember. This function is based on Joey's answer on this page. I know it's not the fastest code but it's seems to work very well for what I need to do.

Just copy the function's code at the end of your script and you can use it like in this example here:

Example:

set "Main_String=This is just a test"
set "Search_String= just "

call :FindString Main_String Search_String

if "%_FindString%" == "true" (
    echo String Found
) else (
    echo String Not Found
)

Note that you don't need to add % to your variables when giving them to this function, it will automatically take care of this. (This is a method that I found which it letting me use spaces in my function's arguments/variables without the need of using undesirables quotes in them.)

Function:

:FindString

rem Example:
rem 
rem set "Main_String=This is just a test"
rem set "Search_String= just "
rem 
rem call :FindString Main_String Search_String
rem 
rem if "%_FindString%" == "true" echo Found
rem if "%_FindString%" == "false" echo Not Found

SETLOCAL

for /f "delims=" %%A in ('echo %%%1%%') do set str1=%%A
for /f "delims=" %%A in ('echo %%%2%%') do set str2=%%A

echo.%str1%|findstr /C:"%str2%" >nul 2>&1
if not errorlevel 1 (
   set "_Result=true"
) else (
   set "_Result=false"
)

ENDLOCAL & SET _FindString=%_Result%
Goto :eof
Frank Einstein
  • 597
  • 6
  • 15