Search code examples
batch-filecmdfindstr

Why does FINDSTR not find the searched string with space in my batch file?


So I am running a FINDSTR command to search a file for the text [errorCode: 0] and using the option /v to output the lines which do not contain this string. This is the used code:

@findstr /i /v "\[errorCode: 0\]" file1.log >>file2.txt

But this puts all the contents of file1.log to file2.txt.

What am I doing wrong?


Solution

  • Use the following command line:

    @%SystemRoot%\System32\findstr.exe /I /L /V /C:"[errorCode: 0]" file1.log >>file2.txt
    

    This runs explicitly a literal string search for [errorCode: 0] because of /L and /C.

    On usage of FINDSTR with its regular expression support not being comparable with regular expression support in other applications and interpreters it is advisable reading its brief help by running findstr /? in a command prompt window and additionally also:

    The command line

    @findstr /i /v "\[errorCode: 0\]" file1.log >>file2.txt
    

    is not producing the expected output because a space character in a just double quoted search string is interpreted as delimiter between multiple search strings. So FINDSTR is searching with this command line for lines containing either the string [errorCode: or the string 0] using a case-insensitive regular expression find and not for lines containing the string [errorCode: 0] and outputs all lines not containing either of these two strings.

    This command line could be also written as:

    • Literal instead of regular expression find searching case-insensitive for [errorCode OR 0] in a line and output all lines not containing either of these two strings:

      @findstr /I /L /V "[errorCode 0]" file1.log
      
    • Literal instead of regular expression find searching case-insensitive explicitly for [errorCode OR 0] in a line and output all lines not containing either of these two strings:

      @findstr /I /V /C:"[errorCode:" /C:"0]" file1.log
      
    • Regular expression find searching case-insensitive explicitly for [errorCode OR 0] in a line and output all lines not containing either of these two strings:

      @findstr /I /R /V /C:"\[errorCode:" /C:"0\]" file1.log
      

    For example file1.log contains:

    Line 1: [errorCode: 0]
    Line 2: [CodeError: 0]
    Line 3: [errorCode: 1]
    Line 4: [noErrCode: 1]
    

    The output of the three command lines above and the initial command line in question is:

    Line 4: [noErrCode: 1]
    

    But the expected output for this example is:

    Line 2: [CodeError: 0]
    Line 3: [errorCode: 1]
    Line 4: [noErrCode: 1]
    

    This is the output on running one of the following command lines:

    @findstr /I /V /C:"[errorCode: 0]" file1.log
    @findstr /I /V /C:"\[errorCode: 0\]" file1.log
    @findstr /I /L /V /C:"[errorCode: 0]" file1.log
    @findstr /I /L /V /C:"\[errorCode: 0\]" file1.log
    @findstr /I /R /V /C:"\[errorCode: 0\]" file1.log
    

    \ is the escape character in a literal and a regular expression string. But in a literal string only the backslash \ itself and the double quote character " must be escaped with a backslash. In a regular expression string the backslash left to a character with a special regular expression meaning results in interpreting the next character as literal character.

    My recommendations for usage of FINDSTR:

    1. Specify one or more strings to compare with always with /C:"..." (or with /C:...) and never with just "..." to get a space in a search string always interpreted as space character.
    2. Specify always /L for a literal or /R for a regular expression find.

    Then the find is always as expected by most users with knowledge of string searching from other applications or interpreters and not knowing the FINDSTR specific rules on interpreting a string to find in double quotes.