# String Search



## scrfix (May 3, 2009)

I am pulling a string from the registry. I already have this covered and know how to accomplish this.

The string will vary so for example sake I am going to utilize:
set /p string=Enter a question with either Vista or XP in it: 

I want to search that string for either the term Vista or XP.

1. How would I accomplish this?

2. I have attempted to utilize Find however that did not work but perhaps I was going on a wrong approach about it. Do you guys have any better solutions?

Thanks,

Wayne


----------



## Squashman (Apr 4, 2003)

What exactly are you hoping for the output to be? Do you want it to perform a task if it finds XP and a different task if it finds Vista?

Find or Findstr should work just fine. If you use find or findstr and it finds XP, you can then check the current errorlevel and perform an additional task based on the errorlevel.


----------



## scrfix (May 3, 2009)

Hi Squahman,

I did not know about findstr. I will try that now.

I just need it to look for the string Vista or the string XP and upon finding that string set a variable to Vista or XP based upon what it finds.

Not a big deal. It shouldn't be hard but I could not get find to work for it. It kept crashing on me.

Wayne


----------



## Squashman (Apr 4, 2003)

```
set /p string=Enter a question with either Vista or XP in it:
Echo %string%|Findstr "XP">Nul
If !errorlevel!==0 set var=XP
Echo %string%|Findstr "Vista">Nul
If !errorlevel!==0 set var=Vista
```
Problem is, what are you going to do if someone enters XP and Vista as an answer to the question.


----------



## scrfix (May 3, 2009)

I am actually pulling the string from a registry entry, not a physical entry. That should not be a problem.


----------



## scrfix (May 3, 2009)

Do you have to use the errorlevel when working with findstr?
I have multiple items within the program that may set the errorlevel not equal to 0 so that may not work for me.

What I am looking to do is search the string for Vista or XP which I know can be done like this.

So if I have this string: Microsoft Window Vista TM Business.
I want to search that string for either the string XP or Vista
This would be findstr /I "Vista XP".

If it finds the Vista string, I would like to set a variable = Vista
If it finds the XP string, I would like to set a variable = XP

However what I am receiving is:

FINDSTR: Cannot open Vista
FINDSTR: Cannot open TM
FINDSTR: Cannot open Business
Windows Vista TM Business

Wayne


----------



## Squashman (Apr 4, 2003)

Why don't you post your batch file so we are not guessing on what you are trying to do.

When checking the errorlevel it is checking the errorlevel of the last cmd executed. So if you check the errorlevel after you do the findstr, just as I gave it to you, it will work.


----------



## scrfix (May 3, 2009)

This is a simplified version of what I am doing however this works.

```
set OS=Microsoft Window Vista TM Business
set Find=Vista REM /* I would like this to contain 2 or more words Vista and XP but do not know if this is possible for what I am attempting to accomplish*/
echo %OS%|findstr /I "%Find%">nul 
if "%errorlevel%" equ "0" (set OS=Vista)
if "%errorlevel%" geq "1" (
set Find=XP
echo %OS%|findstr /I "%Find%">nul
if "%errorlevel%" equ "0" (set OS=XP)
)
 
echo %OS%
pause
```
This actually works however:

There must be an easier way to write this. I plan on adding more keyword phrases to find. I know that I can utilize a for statement for this. I just cannot get one to work.

I am attempting to try to move through each and every string listed in the Find variable and set the OS variable to that keyword phrase that was matched from findstr /I.

So if it matches a string and say that string is XP, then OS will be set to XP. If it finds the string Vista then the OS will be set to Vista. If it finds the string 2000 then the OS will be set to 2000, etc etc etc.

Wayne


----------



## Squashman (Apr 4, 2003)

I guess I am not sure what you are trying to do.
You do know you can get the OS version of the computer using the VER command.


----------



## scrfix (May 3, 2009)

Yes but that only reports back
Microsoft Windows [Version 6.0.6001]

or

Microsoft Windows [Version 5.1.2600]

That doesn't tell me what OS is installed.

I do understand that I could look for 5 and then know it is XP and 6 and know that it is Vista, etc etc. I would rather do the same thing but have it search for XP and Vista. It is the same concept. I would run into the same issue however instead of looking for 1,2,3,4,5,6,7 I am looking for XP, Vista, Me, 2000, 2003, etc etc.

I must not be relaying something correctly so I am going try to relay it again a different way.

1. I am using a registry entry to pull from in order to get my data. This data is not important for my question and will vary at times. This portion of the bat file is already completed and stored into a variable.

2. For this example I am simply going to store a string into a variable.

3. I need to set another variable based upon what is matched in that string.

Example:
:: In step 1 - Get the string I already have completed this task so instead of adding a bunch of code that I do not need help with I am simply using a string for the example. This is not the real string just merely here for the example bat file.

:: Step 1 - Get the string
set OS=Microsoft Windows Vista OS Installed

:: Next Step 2 - Define strings to look for. I would like to search that string for a specific string. I can do this with the findstr /I command. This is where one problem is. I would like to be able to define multiple strings on one line instead of using multiple if statements. Example: set find=XP Vista so when the findstr /I "%find%" "%string%" it would look for either the string XP or the string Vista.

:: Step 2 - Define strings to look for
set find=XP Vista

:: Step 3 - Search the strings below is where a second problem is. This searches for XP or Vista however does not report back to me which one it found. I need it to report back to me that it found Vista or it found XP, etc etc etc.

:: Step 3 - Search the strings
echo %OS%|findstr /I "%Find%">nul

:: Step 4 - Set the variable based upon the string search below is now the real issue is. Because we are using errorlevels for returning basically true or false I have no ability to determine what was actually found and therefore cannot set the variable to the proper setting. If the string above finds XP, I would like to know it found XP and would like to set my variable to XP. If the string search above found Vista, I would like to know it found Vista and would like to set my variable equal to Vista, etc etc etc.

:: Step 4 - Set the variable based upon the string search
if "%errorlevel%" equ "0" (set OS=??)

Any Ideas

Hopefully that helps explain it a little better.


----------



## Squashman (Apr 4, 2003)

UMM, mine reports back.


```
H:\>ver

Microsoft Windows XP [Version 5.1.2600]

H:\>
```
And my Windows 2000 box.

```
Microsoft Windows 2000 [Version 5.00.2195]
```
And Vista 

```
Microsoft Windows [Version 6.0.5219]
```
So yes you can search for XP and 2000 but you could just search for
Version 5.0
Version 5.1
Version 5.2 (This is Server 2003)
Version 6.0


----------



## Squashman (Apr 4, 2003)

```
VER | findstr /i "5.0." > nul
IF %ERRORLEVEL% EQU 0 ECHO Running 2000

VER | findstr /i "5.1." > nul
IF %ERRORLEVEL% EQU 0 ECHO Running XP

VER | findstr /i "5.2." > nul
IF %ERRORLEVEL% EQU 0 ECHO Running Win 2003

VER | findstr /i "6.0." > nul
```


----------



## scrfix (May 3, 2009)

I just saw your findstr's above. I cannot copy and paste them over because IE8 crashes every time I do.
Is there an easier way then to keep having to repeat the findstr over and over and over again.

so I can utilize
set find=5.0 5.1 5.2 6.0

a for statement here to see if it will find that and then set the variable to equal that.
I can do a ton of if statements as well but I was hoping to get around that.

If I utilize the IF statements that will work and it reports back to me that it is Vista. I was merely hoping that I could consolidate and utilize it all on one line as above. That may not be possible for what I am attempting to do however.


----------



## Squashman (Apr 4, 2003)

> Use spaces to separate multiple search strings unless the argument is prefixed
> with /C. For example, 'FINDSTR "hello there" x.y' searches for "hello" or
> "there" in file x.y. 'FINDSTR /C:"hello there" x.y' searches for
> "hello there" in file x.y.


Problem is it won't know which one it matched on.

You could put all your OS versions in a text file that you are looking for and then use a For loop to parse each and line and do a Find on that.



> :: Step 4 - Set the variable based upon the string search below is now the real issue is. Because we are using errorlevels for returning basically true or false I have no ability to determine what was actually found and therefore cannot set the variable to the proper setting. If the string above finds XP, I would like to know it found XP and would like to set my variable to XP. If the string search above found Vista, I would like to know it found Vista and would like to set my variable equal to Vista, etc etc etc.


I don't see how you don't think this is possible. If you do 4 IF statement and check the errorlevel after each and set the OS variable when it is True, you will know what the OS is.


```
set /p string=Enter a question with either Vista or XP in it:
Echo %string%|Findstr "XP">Nul
If !errorlevel!==0 set var=XP
Echo %string%|Findstr "Vista">Nul
If !errorlevel!==0 set var=Vista
Echo %string%|Findstr "2000">Nul
If !errorlevel!==0 set var=2000
```
How does this not tell you what OS is found?


----------



## scrfix (May 3, 2009)

Here is an example:
This works perfectly however requires me to keep adding If statements 

```
Echo %OS% | findstr /i "XP" > nul
IF %ERRORLEVEL% EQU 0 Set OS=XP
Echo %OS% | findstr /i "Vista" > nul
IF %ERRORLEVEL% EQU 0 Set OS=Vista
Echo %OS% | findstr /i "2000" > nul
IF %ERRORLEVEL% EQU 0 Set OS=2000
Echo %OS% | findstr /i "2003" > nul
IF %ERRORLEVEL% EQU 0 Set OS=2003
```
OR


```
VER | findstr /i "5.1" > nul
IF %ERRORLEVEL% EQU 0 Set OS=XP
VER | findstr /i "6.0" > nul
IF %ERRORLEVEL% EQU 0 Set OS=Vista
VER | findstr /i "5.0" > nul
IF %ERRORLEVEL% EQU 0 Set OS=2000
VER | findstr /i "5.2" > nul
IF %ERRORLEVEL% EQU 0 Set OS=2003
```
which I don't mind but it would be easier if I could just add them to a variable instead of having to write them all out again over and over.

:: set find=XP Vista 2000 2003 REM etc etc etc
:: OR
set find=5.0 5.1 5.2 5.3 6.0 7.0 REM etc etc etc

VER | findstr /i "%find%" > nul
set OS=my operating system are version string here from the findstr command

for %%T in ("%OS%") do findstr /I "%find%" %%T

REM or something close to that if that is not correct. I still do not have these for statements down. I have not tested the one above.

If it was set up like the latter than I could just add strings to the find variable and that is it rather than to keep having to copy and paste the same IF statement over and over again.


----------



## TheOutcaste (Aug 8, 2007)

This will use a For loop to loop through the values in the *_Find* variable (Using a command name as a variable name is not recommended, that's one reason I always use an underscore to start variables/labels)
The *_Find* variable items _must_ be enclosed in quotes, and must be separated by a space. Items to search for can contain spaces.

If there are multiple matches (string contains xp and vista for example) the first one found is the one that will be used)


```
@Echo %dbg%Off
SetLocal EnableDelayedExpansion
Set _String=Installed OS is hello world XP
Set _Find="Hello World" "2000" "XP" "Vista"
For %%I In (%_Find%) Do (
Echo %_String% |Findstr /I /C:%%I>Nul
If !ErrorLevel!==0 (Set _OS=%%I)&Goto _Found
)
Echo No match in %_String%
Goto :EOF
:_Found
Echo Found %_OS% in this string: %_String%
```
So with my test string, this will find hello world instead of XP



scrfix said:


> Do you have to use the errorlevel when working with findstr?
> I have multiple items within the program that may set the errorlevel not equal to 0 so that may not work for me.


It's the only way to determine the result of find or findstr:
0=F*0*und
1=M*1*ssing

The %Errorlevel% variable is a special variable if Command Extensions are enabled. It is only available on Win2k and later. If you need to check on Win9x or WinNT you have to use two *IF ERRORLEVEL X* statements
It is set by every command that executes (there are some that don't set it, or leave it in a random state) _unless you've set it with a value_. Another reason I use an underscore to start all variable names.

HTH

Jerry


----------



## scrfix (May 3, 2009)

what is 
@echo %dbg%Off

I have not seen before.


----------



## Squashman (Apr 4, 2003)

Jerry uses that as a debugging option when he writes batch files. He uses that to toggle echo on or off.


----------



## TheOutcaste (Aug 8, 2007)

scrfix said:


> what is
> @echo %dbg%Off
> 
> I have not seen before.


I usually edit that out before posting but it's just as Squashman says.
If *dbg* is not defined, the first line expands to:
*@Echo Off
*
If *dbg* is set to anything, like 1 or yes, you get this:
*@Echo 1off*
or
*@Echo yesoff*
And Echo doesn't get turned off, it just echos *1off* or *yesoff* to the screen.
I have two little batch files in my Scripts folder (which is included in my path statement) to toggle this:
dboff:
*Set dbg=*
dbon:
*set dbg=1
*
Jerry


----------



## scrfix (May 3, 2009)

Jerry,

I notice that it starts SetLocal EnableDelayedExpansion
However it doesn't end it. Does this matter for the bigger picture of things?


----------



## TheOutcaste (Aug 8, 2007)

Only if you need to disable delayed expansion, or need to end the Setlocal. When the batch file ends, it does an Endlocal.
If you do use an Endlocal command, or after the file ends, the values of any variables defined or changed after the Setlocal will be discarded.

You can preserve the values by doing set statements on the same line as the Endlocal command:
Endlocal&Set _Var1=%_Var1%&Set _Var2=%_Var2%


----------



## scrfix (May 3, 2009)

Jerry,

/***************************************/ 
/* *Update: *
/* Nevermind, I figured it out.
/* I had added SetLocal DisableDelayedExpansion
/* before Set _OS=%_OS:"=%
/*
/* As soon as I put it after, it worked.
/***************************************/

I keep getting some weird results when I try to remove the quotes

Here is what I receive
"Vista" in this string: "2000" "XP" "Vista" "2003"

I have attempted the set _OS=%_OS:%"=%
and then I receive ""Vista"""

I am looking just to have Vista

What am I doing wrong?


----------



## TheOutcaste (Aug 8, 2007)

Add the ~ modifier to the loop variable in the set statement to remove the surrounding quotes:


```
If !ErrorLevel!==0 (Set _OS=%%[COLOR=Red][B]~[/B][/COLOR]I)&Goto _Found
```


----------



## TheOutcaste (Aug 8, 2007)

scrfix said:


> before Set _OS=%_OS:"=%
> I have attempted the set _OS=%_OS:*%*"=%
> and then I receive ""Vista"""


I'm guessing this extra % is a typo as you had it right in the beginning.

I don't know why it's doing that. *Set _OS=%_OS:"=%* works fine for me to remove the quotes, as does using *%%~I*, or even this:
*Set _OS=:~1,-1%*


----------



## scrfix (May 3, 2009)

You would have to see my update. I changed it over to yours anyway. That is a much more effecient way of removing them.

Wayne


----------

