0

I have a batch file that will check for updates within a directory then copy any new files or recently modified files to the other selected directory, however I'm unsure how to check the source directory for say two files that have just a revision number or letter difference: example.pdf and exampleA.pdf. I need to compare the files somehow by both string and date modified. So if the source directory has a new file that's been saved as exampleB.pdf, I need the batch to copy that file into the destination directory as example.pdf instead of the new filename. I want the copied file to have the core filename if you will, being just example.pdf

Any help would be much appreciated.

Thanks

    @Echo Off
:: variables
set drive=G:\Backup
set backupcmd=xcopy /s /c /d /e /h /i /r /y

set revchk=if 

Set _Delay=10
Set _Monitor=C:\Users\me\Desktop\Test Source Folder
Set _Base=%temp%\BaselineState.dir
Set _Chck=%temp%\ChkState.dir
Set _OS=6
Ver|Findstr /I /C:"Version 5">Nul
If %Errorlevel%==0 Set _OS=5 & Set /A _Delay=_Delay*1000
:_StartMon
Call :_SetBaseline "%_Base%" "%_Monitor%"
:_MonLoop
If %_OS%==5 (Ping 1.0.0.0 -n 1 -w %_Delay%>Nul) Else Timeout %_Delay%>Nul
Call :_SetBaseline "%_Chck%" "%_Monitor%"
FC /A /L "%_Base%" "%_Chck%">Nul
If %ErrorLevel%==0 Goto _MonLoop

echo ### Backing up...
%backupcmd% "C:\Users\me\Desktop\Test Source Folder" "C:\Users\me\Desktop\Test Destination Folder"


echo ### Checking for new file revisions...



Echo.Backup Complete!
Goto :_StartMon
:::::::::::::::::::::::::::::::::::::::::::::::::::
:: Subroutine
:::::::::::::::::::::::::::::::::::::::::::::::::::
:_SetBaseline
If Exist "%temp%\tempfmstate.dir" Del "%temp%\tempfmstate.dir"
For /F "Tokens=* Delims=" %%I In ('Dir /S "%~2"') Do (
Set _Last=%%I
>>"%temp%\tempfmstate.dir" Echo.%%I
)
>"%~1" Findstr /V /C:"%_Last%" "%temp%\tempfmstate.dir"
Goto :EOF
cheapkid1
  • 469
  • 7
  • 18
  • 32

1 Answers1

2

The Batch program below assume that newer files have revision numbers or letters in ascending alphabeticall order, so the last listed file is the newest one. This way, the program identify a set of files that begin with the same name, and copy the last one of the set with the name of the first one in the set.

@echo off
setlocal EnableDelayedExpansion
set baseName=
for %%a in (*.*) do (
   if not defined baseName (
      rem Is first name of first set
      set baseName=%%~Na
      set baseExt=%%~Xa
      set lastName=%%~Na
   ) else (
      rem Check if this name begin with same baseName
      set name=%%~Na
      for %%b in (!baseName!) do set name=!name:*%%b=!
      if "!name!" neq "%%~Na" (
         rem Yes: Is next name of same set
         set lastName=%%~Na
      ) else (
         rem No: Is first name of next set: copy previous set and pass to next one
         ECHO copy "!lastName!!baseExt!" "C:\dest\dir\!baseName!!baseExt!"
         set baseName=%%~Na
         set baseExt=%%~Xa
         set lastName=%%~Na
      )
   )      
)
rem Copy last set
ECHO copy "!lastName!!baseExt!" "C:\dest\dir\!baseName!!baseExt!"

Test the program and remove ECHO commands if it works as you want.

Aacini
  • 65,180
  • 12
  • 72
  • 108
  • Thanks, I'll test it and let you know. I appreciate your response. – cheapkid1 Nov 07 '12 at 22:07
  • Don't I need a source directory in here as well, I only see a dest directory? – cheapkid1 Nov 09 '12 at 15:51
  • I can't get it to work, it runs, but doesn't copy latest file rev from source folder to destination folder, or even the original file. Any suggestions? – cheapkid1 Nov 09 '12 at 16:15
  • @cheapkid1: Please note that the program just _show_ the commands that it _would_ execute. As I said before, you must test (execute) the program in the directory that have the files and check if the `copy` commands SHOWN meets your requirements. If so, remove the `ECHO ` part so the copy commands be really executed; otherwise, post here the commands shown by the program and a list of your files on disk... – Aacini Nov 10 '12 at 05:37
  • That worked, I removed the echos and it worked. Now, how do I incorporate that into my batch, because I want this running continuously? Right now, my batch runs and checks the source directory every 10 seconds. Is there some place in my batch where I can slip yours in to run seemlessly? – cheapkid1 Nov 14 '12 at 21:40
  • How do I exclude copying itself in the batch you posted? – cheapkid1 Nov 15 '12 at 20:58
  • @cheapkid1: Insert `if "!lastName!" neq "%~N0"` before the two `copy` commands in the same line, ie: `if "!lastName!" neq "%~N0" copy ...` – Aacini Nov 16 '12 at 02:59
  • It works in a sense of not copying itself, but now it doesn't rename to the original filename based on the copy latest revision letter. Any thoughts? It will copy say if there was an original file.xls and a fileA.xls, and I create fileBxls it now will copy the A and B rev instead of copying the rev B and naming it the original file.xls to the desination folder. – cheapkid1 Nov 16 '12 at 13:18
  • Also, since the number of files in the source directory are many, is there a way to only copy what's been modified or what's new? Or would that need to be another posted question? Right now, it works if I call the batch you wrote, but it takes forever to copy 8k+ files in the source directory. Any thoughts/help would be most appreciated. Thanks – cheapkid1 Nov 16 '12 at 15:31
  • 1/2: Please be sure that original version works correctly. The modification to exclude the copy of itself have no relation to the original code. Double check your file names. Note that the comparison of names is case sensitive, so if a revision have any letter in different case, it is taken as a different base name (of course, it is!). To avoid this problem, insert /I switch in the name comparison: `if /I "!name!" neq "%%~Na" (`. – Aacini Nov 16 '12 at 19:16
  • 2/2: I am pretty sure that the _file names checking process_ is very fast. Of course, if the files to copy are large or numerous, the process takes a while (buy a faster computer! :-). You may check this by reinserting the `ECHO` part in copy commands and test how long the program takes to _just display_ the file names. To copy modified or new files only, use `xcopy /M` command; you may select the files that will be copied the first time with `attrib +A`. – Aacini Nov 16 '12 at 19:16
  • 1/2 Reply: The original version works correctly, however as you said it has to be placed in the source directory, if it copies all files in that directory, that file is included withing the list of files in that folder that it looks at and copies. The filenames are properly related with exact case matching between original and latest revs (except of course the rev letter itself). What I've devised is calling your batch from mine and adding some delete files code at the end for my batch and your batch in the dest. directory. – cheapkid1 Nov 16 '12 at 20:59
  • You must insert /I switch in the if command that check the name of the batch file!: `if /I "!lastName!" neq "%~N0" copy ...`, of course! – Aacini Nov 16 '12 at 21:11
  • 2/2 Reply: You're right it is fast to check the filenames, but when I have 8k files in the dir it's bound to wait a while initially(no matter how fast the PC is), however if after that process is finished, let's say there's a new file that's created in the source dir, causing my batch to call yours once again, but using your batch as a sort of sub routine, it copies all the source files all over again, and not just what's new. If I manually copy the source directory then place xcopy /M as you said instead of the copy commands in your batch, that should copy mod/new files there after, right? – cheapkid1 Nov 16 '12 at 21:16
  • I want to thank you by the way for all your help and input, I really do appreciate it. I can grasp some concepts, but I'm not very savy with batch writing. – cheapkid1 Nov 16 '12 at 21:17
  • I'll try your suggestions and see what results I get. Thanks again. – cheapkid1 Nov 16 '12 at 21:19
  • I've tried to incorporate your batch into mine, but it doesn't copy any files and it says it cannot find file "!lastName!!baseExt!". See what I've put on my post. – cheapkid1 Nov 29 '12 at 17:29
  • I subroutined your bit of code and it works, however it displays to specify a file name of a directory name on the target for each file that it wants to copy. Also let's say there's example.pdf and exampleA.pdf and exampleB.pdf and I delete exampleB.pdf how can I get latest file which would be exampleA.pdf to re-copy since it's the latest revision to the desination folder named example.pdf? – cheapkid1 Nov 29 '12 at 21:02