forfiles /D +12/1/%2 /C "cmd /c if /I @FDATE LEQ 12/31/%2 move @file %3\Archive\12-%2 >NUL"
The forfiles is supposed to be targeting all files with last modified dates between 12/1/2015 and 12/31/2015 (including the 1st and 31st), and moving them to archive. For reasons unknown, some files with the last modified date 12/3/2015, and 12/9/2015 are not being moved. Additionally, ALL files with last modified date of 12/4/2015 thru 12/8/2015 are not being moved.
Steps taken to debug: Processed different months: January, Feb, etc and Archiving was successful. Permissions have been checked, and verified. Manually archived the unmoved files. Created copies of the unmoved files and still encounter the same issues. The last thing I did was replace
if /I @FDATE LEQ 12/31/%2 move @file %3\Archive\12-%2 >NUL
with
echo @FDATE
to ensure that ALL the modified dates are visible. Modified dates for the files that aren't being successfully moved and archived are visible.
As @JosefZ already pointed out in his comment,
ifis not capable of comparing date values.However, to filter files by a certain range for the modification date, you could use two nested
forfilesloops:Development
The outer loop of the two nested
forfilesloops enumerates items with the given lower bound of the range for the modification dates (the date is given in formatdd-MM-yyyyas per the (short) date format of my system; check out the help text offorfiles /?to find out the proper format for your system):This returns all items modified on 1st of December 2015 or later.
The inner loop is then used to return only items that have been modified on 31st of December 2015 or earlier. To achieve this, we need to create a command line based on the following:
The mask after
/Mneeds to be set to the@filevalue returned by the outer loop, so the inner one iterates once only per each iteration of the outer one; so the inner loop simply filters each single item received by the outer one by its modification date. The location after/Pdoes not need to be specified as the outer loop executes the inner loop (or in general the command after/C) already from the directory the currently iterated item is located (this is also true if the/Sswitch is provided to process sub-directories also).The challenge now is to hide the variables like
@fileof the inner loop from the outer loop. The trick is the use the hexadecimal code substitution feature offorfiles; for instance,0x20will be replaced by a space,0x22by a quotation mark,0x40by the@-sign and0x78is the letterx. Since this substitution is done even before replacement of the@-variables, we need to state00x7840to hide the@symbol from the outer loop and thus to avoid replacement of@file, for example, because the@will become0x40, so the inner loop receives0x40file, which will be converted back to@fileand then immediately replaced by its value.So the command line with the nested
forfilesloops could look like this:To filter out directories and return files only, you need to check
@isdir:Finally, to avoid empty lines or error messages to be returned by
forfiles, use redirection:Consult also the following posts:
forfilesloops properly (so that the inner body expands variables of both iteration levels)?forfiles /C "forfiles forfiles")