Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write a search pattern to include a space in findstr?

Tags:

regex

findstr

People also ask

How do you use findstr example?

Specifies a file or files to search. You'll need to 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.

How do I search for a string in a command prompt?

You can run findstr from the command line or as a batch file. Open a new command line prompt by clicking on the Windows-key, typing cmd.exe, and selecting the result. Alternatively, use the Run command to open findstr.

Does findstr support regex?

Search for a text string in a file (or multiple files) unlike the simple FIND command FINDSTR supports more complex regular expressions.

What is the difference between find and findstr?

The find program supports UTF-16, which findstr doesn't; on the other hand, the findstr program supports regular expressions, which find does not. The reason why their feature sets are unrelated is that the two programs are unrelated. The find program came first.


If you use spaces, you need the /C: option to pass the the literal string(s) to the regex /R option.
Once the it gets to the regex, it's treated as a regex.

That said, this is typical MS trash.

Use two regex search strings

The bottom line is that you have to use 2 strings to handle cases where
Load frm is at the beginning like so:

  • Load frm apples bananas carrots

OR in the middle like so:

  • some other text Load frm and more.

Version without character classes

Below is using XP sp3, windows 7 may be different, both are trash!

findstr /N /R /C:" *Load *frm" /C:"^Load *frm" test.txt

7:Load frm is ok    
8:    Load     frm is ok  

Mind the Colon

NOTE: The colon in /C: is MANDATORY for this to work.

If you leave out the colon then findstr's error handling is just to treat /C as an invalid option, ignore that invalid option and go ahead anyway. Leading to unexpected and unwanted output.

Equivalent version using character classes

findstr /N /R /C:"[ ][ ]*Load[ ][ ]*frm" /C:"^Load[ ][ ]*frm" test.txt

Character classes breakdown

// The first regex search string breaks down like this:
[ ]   // require 1 space
[ ]*  // optional many spaces
Load  // literal 'Load'
[ ]   // require 1 space
[ ]*  // optional many spaces
frm   // literal 'frm'

// The second regex search string breaks down like this:
^     // beginning of line
Load  // literal 'Load'
[ ]   // require 1 space
[ ]*  // optional many spaces
frm   // literal 'frm'

A real regex might be \bLoad\s+frm


Use the /c option:

findstr /n /c:"Load frm" *.*

From the help (findstr /?):

/C:string  Uses specified string as a literal search string.

Use word delimiter regex

I used the the special \< "beginning of word" regex symbol.

I tried this on the Win10 version of findstr. But according to Microsoft this special \< symbol has been in findstr.exe ever since WinXP.

Full (and painful) breakdown of many options that do NOT work below.

At the very bottom: what actually worked.

The sample file itself

C:\>type lines.txt
Load frmXYZ                         // This line should match.
If ABCFormLoaded Then Unload frmPQR // This line should NOT match.
pears Load frm grapes pineapples    // This line should match.
                                    // This blank line should NOT match.
LOAD FRMXYZ                         // This line should match.
IF ABCFORMLOADED THEN UNLOAD FRMPQR // This line should NOT match.
PEARS LOAD FRM GRAPES PINEAPPLES    // This line should match.
                                    // This blank line should NOT match.
load frmxyz                         // This line should match.
if abcformloaded then unload frmpqr // This line should NOT match.
pears load frm grapes pineapples    // This line should match.

Wrong. With regular execution space is treated as delimiter.

C:\>type lines.txt | findstr /N "Load frm"
1:Load frmXYZ                         // This line should match.
2:If ABCFormLoaded Then Unload frmPQR // This line should NOT match.
3:pears Load frm grapes pineapples    // This line should match.
9:load frmxyz                         // This line should match.
10:if abcformloaded then unload frmpqr // This line should NOT match.
11:pears load frm grapes pineapples    // This line should match.

Wrong: With Regex option space is STILL treated as delimiter.

C:\>type lines.txt | findstr /N /R "Load frm"
1:Load frmXYZ                         // This line should match.
2:If ABCFormLoaded Then Unload frmPQR // This line should NOT match.
3:pears Load frm grapes pineapples    // This line should match.
9:load frmxyz                         // This line should match.
10:if abcformloaded then unload frmpqr // This line should NOT match.
11:pears load frm grapes pineapples    // This line should match.    

More right but still wrong. With /C option we now get preserved spaces but don't find other character cases.

C:\>type lines.txt | findstr /N /R /C:"Load frm"
1:Load frmXYZ                         // This line should match.
3:pears Load frm grapes pineapples    // This line should match.

Wrong. /I for "Ignore Case" does not help. We get matches from within words we did not want.

C:\>type lines.txt | findstr /N /R /I /C:"Load frm"
1:Load frmXYZ                         // This line should match.
2:If ABCFormLoaded Then Unload frmPQR // This line should NOT match.
3:pears Load frm grapes pineapples    // This line should match.
5:LOAD FRMXYZ                         // This line should match.
6:IF ABCFORMLOADED THEN UNLOAD FRMPQR // This line should NOT match.
7:PEARS LOAD FRM GRAPES PINEAPPLES    // This line should match.
9:load frmxyz                         // This line should match.
10:if abcformloaded then unload frmpqr // This line should NOT match.
11:pears load frm grapes pineapples    // This line should match.

Right. Use special "Beginning of word" regex symbol. Matches beginning-of-line or space.

Either case sensitive:

C:\>type lines.txt | findstr /N /R /C:"\<Load frm"
1:Load frmXYZ                         // This line should match.
3:pears Load frm grapes pineapples    // This line should match.

or ignoring case

C:\>type lines.txt | findstr /N /R /I /C:"\<Load frm"
1:Load frmXYZ                         // This line should match.
3:pears Load frm grapes pineapples    // This line should match.
5:LOAD FRMXYZ                         // This line should match.
7:PEARS LOAD FRM GRAPES PINEAPPLES    // This line should match.
9:load frmxyz                         // This line should match.
11:pears load frm grapes pineapples    // This line should match.