0

imagine that I have 2 folders:

  • C:\FolderData (will be incremented daily with new files)
  • C:\FolderTemp (Needs to have only files from the day before executing, excluding hours/timestamp)

The FolderData will receive filenames that if not for date would be equals, as in:

  1. SYS_PURCHASES_20170612.xls
  2. SYS_PURCHASES_20170613.xls
  3. SYS_PURCHASES_20170614.xls

If I run the .bat file today I need that only the SYS_PURCHASES_20170613.xls be copied over to FolderTemp.

I tried using robocopy but apparently it can't receive the same value for minage and maxage

robocopy "C:\FolderData" "C:\FolderTemp" /minage:1 /maxage:1

Also, if I try:

robocopy "C:\FolderData" "C:\FolderTemp" /minage:1 /maxage:2

It will bring both SYS_PURCHASES_20170612.xls and SYS_PURCHASES_20170613.xls, which is not what I need.

Other than that, I tried using forfiles but also with no avail.

forfiles /p C:\FolderData /D -1 /C "/C /copy /y @file C:\FolderTemp"

or even

forfiles /p C:\FolderData /D -1 /C "/C /copy /y C:\FolderData\@file C:\FolderTemp"

And other variables but it returns something along the line "the system can't return the specified file" times the number of files in the folder.

Note that there are other processes involved bellow that should be ignored, It's just that I can't figure out how to do the step above.

All steps my batch filed needs to do:

  1. Copy from folder1 files from 1 day prior to folder2 (what I need help)
  2. Remove last 9 digits from all files from folder2 (will remove the date, used the loop on this solution) so the file will be SYS_PURCHASES.xls
  3. Move and replacing the files from folder2 to folder3 (using a simple move /y)
mrbTT
  • 1,399
  • 1
  • 18
  • 31
  • It's `/maxage:1`, not `/maxage1`; but you need `/maxage:2`, I guess. `forfiles` cannot work, because `/D -1` says to take files one day old or older (or, correctly spoken, last modified yesterday or eralier). – aschipfl Jun 14 '17 at 17:29
  • There is actually a work-around using `forfiles` -- see this post: [FORFILES date -after- (date calc in cmd file)](https://stackoverflow.com/a/36585535) – aschipfl Jun 14 '17 at 17:40
  • @aschipfl the `maxage1` and `maxage1` was a typo on my Question, will fix it and then read the post you sent, ty. – mrbTT Jun 14 '17 at 17:46
  • Alright. `robocopy` also regards the time, so a file is considered a day old when it has been created/modified yesterday at the same time. `forfiles` however does not care about the time, so a file is considered a day old when it has been created/modified yesterday. – aschipfl Jun 14 '17 at 18:02
  • That was waaaaaaay advanced for me to understand where do I add the copy command inside the forfiles's inside loop, could you elaborate where the copy and folders would need to be? – mrbTT Jun 14 '17 at 18:14

1 Answers1

1

Since you want to touch the files from yesterday only, I would use forfiles, because this command only regards the date but not the time, when specifying the /D option. robocopy instead also regards the time, which is probably not what you want.

This is a possible way:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_SOURCE=C:\FolderData"
set "_TARGET=C:\FolderTemp"
set "_MASK=?*_????????.*"
set /A "_DAYS_AGO=1"

rem // Check given age and calculate interim value `PREV` needed for `forfiles`:
(if %_DAYS_AGO% LSS 0 set "_DAYS_AGO=0") & set /A "PREV=_DAYS_AGO+1"
rem // Let `forfiles` output the filtered files and capture them by `for /F`:
for /F "delims= eol=|" %%F in ('
    rem/ Use two nested `forfiles` loops to filter for files of specified day: ^
        ^& forfiles /P "%_SOURCE%" /M "%_MASK%" /D -%_DAYS_AGO% ^
        /C "cmd /C if @isdir==FALSE > nul 2>&1 forfiles /M @file /D -%PREV% || echo @file"
') do (
    rem // Store current file name and extension:
    set "FILE=%%~nF" & set "FEXT=%%~xF"
    setlocal EnableDelayedExpansion
    rem // Copy the file and remove the last 9 characters from its name:
    > nul copy /Y "!_SOURCE!\!FILE!!FEXT!" "!_TARGET!\!FILE:~,-9!!FEXT!"
    endlocal
)

endlocal
exit /B
aschipfl
  • 33,626
  • 12
  • 54
  • 99
  • Thanks for the reply, I'm still checking the script. Is there a way to ignore file extensions? Because there will be .xls, .xlsx and .txt files in the Folder. – mrbTT Jun 19 '17 at 17:32
  • 1
    Sure; the variable (constant) `_MASK` defines the pattern to match, so just change the appropriate line: `set "_MASK=?*_????????.*"` – aschipfl Jun 19 '17 at 17:34
  • It didn't work :/ Does it uses date created or modified? Also tried changing the days ago from 0 to 10 (which are the dates I modified the files in the folder) and nothing... Any idea why? – mrbTT Jun 19 '17 at 17:48
  • 1
    Sorry, I made a mistake concerning redirection -- see my edit. `forfiles` (as well as `robocopy`) regards the last modification date... – aschipfl Jun 19 '17 at 18:49
  • Hey, that did It! You made all the steps even thou I only needed just the one to move, thanks a bunch, I'll mark it as the answer. Now I need to check if I can pass the source and target folder as parameters! – mrbTT Jun 19 '17 at 19:15
  • Got it, changed the constants to `set "_SOURCE=%1"` and `set "_TARGET=%2"`. Then I executed the bat file as cmd `> copy.bat c:\FolderData c:\FolderTemp` – mrbTT Jun 19 '17 at 19:26
  • You're welcome! You should write `%~1` and `%~2` instead to avoid trouble with quoted arguments. And you should not name a batch file like a command (`copy`) in order to avoid confusion... – aschipfl Jun 19 '17 at 20:07
  • I will... But I just got a new specification that I wasn't considering and I won't be able to use the solution you provided... Now I need to get the files where the date in the FILENAME equals 2 days prior... Since it's completely new thing, I'll create another question, cheers! – mrbTT Jun 19 '17 at 20:09