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

后端 未结 4 1476
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-29 20:02

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 f

相关标签:
4条回答
  • 2020-12-29 20:13

    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
    
    0 讨论(0)
  • 2020-12-29 20:18

    Use the /c option:

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

    From the help (findstr /?):

    /C:string  Uses specified string as a literal search string.
    
    0 讨论(0)
  • 2020-12-29 20:28

    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

    0 讨论(0)
  • 2020-12-29 20:39

    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.
    
    0 讨论(0)
提交回复
热议问题