The findstr
command checks the very first search expression and changes to regular expression mode when a meta-character is found or to literal mode otherwise, unless you explicitly predefine the mode by /L
(literal) or /R
(regular expression).
But findstr
is a nasty beast since there are still some problems even with /L
:
- wrong results may be returned with multiple literal search strings, unless you specify
/I
to do case-insensitive searches; but this is not a problem here anyway since you are dealing with directory and file names, which are treated case-insensitively by Windows anyway;
- although in literal mode, escaping of meta-characters like
.
, [
, ]
, ^
, $
, \
, *
and ?
still occurs when there is a \
in front; you could just double all \
to work around that;
So the following code should work in most situations; delayed expansion is enabled herein by cmd /V
, which is required to read the interim variable FILE
that is written and read in the same command line:
forfiles /S /M "*.txt" /D -1 /C "cmd /C if @isdir==FALSE (set FILE=@path) & cmd /V /C echo(!FILE:\=\\!" > "exclude.txt"
forfiles /S /M "*.txt" /C "cmd /C if @isdir==FALSE echo @path" > "all.txt"
for /F "delims=" %%X in ('findstr /V /L /I /X /G:"exclude.txt" "all.txt"') do (
echo(%%X
)
I inserted if @isdir==FALSE
here to not match directories whose names end in .txt
. Also I added /X
to findstr
in order to match whole lines/paths only.
Regard that literal findstr
search strings are limited to a length of 511 bytes (after doubling \
), which can easily be reached with file paths.
However, what about a different approach that avoids findstr
at all?
Here is a post I once provided for returning items newer than a relative date with forfiles
: FORFILES date -after- (date calc in cmd file).