39

I want to search all files in a certain directory for occurrences of statements such as

  Load frmXYZ

I am on Windows 7, using the findstr command. I tried:

  findstr /n Load.*frm *.*

But this gives me unwanted results such as:

 If ABCFormLoaded Then Unload frmPQR

So I tried to put a blankspace between Load and frm and gave the command like this:

 findstr /n Load frm *.*

But this simply searched for all occurrences of the word load or all occurrences of the word frm. How do I get around this problem?

StackzOfZtuff
  • 2,534
  • 1
  • 28
  • 25
CodeBlue
  • 14,631
  • 33
  • 94
  • 132
  • Aren't you missing the `/r` option to enable regexes, anyway? – Joey Mar 20 '12 at 15:21
  • It says /r uses search strings as regular expressions. So does it mean that "space" will then be treated as part of the regular expression? Let me try. – CodeBlue Mar 20 '12 at 15:27
  • Ok, I tried, but I am not sure how to use it. – CodeBlue Mar 20 '12 at 15:28
  • This is a few years stale, but I generally just use `.` instead of space, since most of the time I care about the other letters in the expression by position and whether the space is really a space isn't as important. `findstr /n /r Load.frm *.*` (Don't get me wrong, `/c` is useful, but half the time it doesn't seem to work for me anyways) – ebyrob Aug 01 '18 at 14:34

4 Answers4

45

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

StackzOfZtuff
  • 2,534
  • 1
  • 28
  • 25
33

Use the /c option:

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

From the help (findstr /?):

/C:string  Uses specified string as a literal search string.
Joey
  • 344,408
  • 85
  • 689
  • 683
9

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.
Community
  • 1
  • 1
StackzOfZtuff
  • 2,534
  • 1
  • 28
  • 25
-1

This piece of code will only allow letters, numbers, underscore and white space in keyword:

set /p keyword="Enter keyword: " || Set keyword=

set keyword_replaced=%keyword: =_%

echo %keyword_replaced%| findstr /r "[^0-9a-zA-Z_]" > nul
if errorlevel 1 goto noexit
echo special characters in keyword not allowed (except space and _), TERMINATING
timeout 4
exit /b 0
:noexit