I'm trying to create a list of files created yesterday.
I've got the below working without /c:"cmd /c echo @path" but I want the full path.
forfiles /s /d -1 /m *.txt /c:"cmd /c echo @path" > a.txt
forfiles /s /m *.txt /c:"cmd /c echo @path" > b.txt
FOR /f "delims=; tokens=*" %%X IN ('findstr /v /g:a.txt b.txt') DO (
echo %%X
)
What is the best way to get around the issue with using findstr with a path containing backslashes? Do I need to replace all the backslashes in the comparison files with some other symbol and then change it back later or is there an easier way to do it in the findstr line?
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
:
/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;.
, [
, ]
, ^
, $
, \
, *
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).