18

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
  • 344,408
  • 85
  • 689
  • 683
LCC
  • 1,170
  • 1
  • 17
  • 28

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
  • 344,408
  • 85
  • 689
  • 683
  • 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
27

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
  • 78,592
  • 17
  • 171
  • 225
  • +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 we don't need to add any % character to our variables after the "FindString" function. It's automatically done internally in our custom function.
(It's a great solution for Batch functions that allows us to easily use values that can contain spaces for the function arguments without needing to care about quotes or anything like that.)

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
  • 676
  • 8
  • 15