user3656918
user3656918

Reputation: 3

Adding copy\overwrite logic to a batch file

Good day. I am trying to write my first batch file. I finally got it do to the most basic of tasks, and have read much here that helped including tutorials. I have not yet found an article to help me put what I'm looking for together. My search-fu is weak.

I want my batch file to copy all files every 30 minutes. However, if it comes to a file that has been updated, I want it to copy but not replace the existing in the destination. I'm assuming it would just add the (1) or 'copy' to the file name. I'm not sure if I used the proper switches or need to change them based on what I'm looking for. I think they're good, but I digress.

Here is the batch that I created without the logic:

REM Backup files 30 minutes
@echo off
:start
XCOPY "C:\source directory" "C:\target directory" /d /c /s /r /y /i
TIMEOUT /t 1800 /nobreak
goto start

Upvotes: 0

Views: 182

Answers (1)

GolezTrol
GolezTrol

Reputation: 116100

Normal behaviour is to overwrite the file, or to fail (depending on the action). The (1) or (copy) postfixes are special features of Windows Explorer (the shell). If you want similar behaviour in your script, you'll have to implement it yourself.

The easiest thing (also to prevent a lot of (1), (2) .. (N) files, is to create separate folders. You can create a folder with a timestamp and copy all modified files to it.

To detect which files are modified, you might use the Archive flag of the files. When a file is modified, its Archive flag is set. XCopy has the possibility to copy only those files which have the flag set. Actually the main purpose of this flag is to determine modified files (or at least, files you want to archive).

So my suggestion:

  • Create a folder with a timestamp in the name. You may want to use the answer to this question for that.
  • Use XCopy with the /M parameter. /M copies only files with the Archive attribute, and clears the attribute afterwards.
  • Try to delete the directory using rd or rmdir, but without the /S parameter. It will fail if it contains files, but this way you will prevent a lot of empty directories.

Before implementing this, make sure that the process which modifies the files, also sets the Archive attribute again. It should do that automatically, but it can't hurt to test this.

-edit- Per request an example:

REM Backup files 30 minutes
@echo off
:start

REM generate a timestamp value that can be used as a file name.
setlocal TIMESTAMP=%DATE:~10,4%-%DATE:~4,2%-%DATE:~7,2%-%TIME:~0,2%-%TIME:~3,2%-%TIME:~6,2%

REM Not needed, I think: Creating the directory yourself.
REM md "C:\target directory\%TIMESTAMP%"

REM /S for recursive. /I should create target directory? /M for backup mode.
XCOPY "C:\source directory" "C:\target directory\%TIMESTAMP%" /M /S /I

REM Not needed, I think: Removing the directory (if it's empty).
REM rd "C:\target directory\%TIMESTAMP%"

TIMEOUT /t 1800 /nobreak
goto start

I think /I already solves the other issues. It assumes that target is a directory if it doesn't exist. That makes me assume that it will in fact create that directory if it doesn't exist, and probably only if there is anything to copy. If that is right, you also won't have to remove the directory if it's empty.

Considering cleanup: Remember that this method (using /M) only copies files that have changed. If you cleanup old directories, you should make sure to copy the entire folder first. The timestamped folders will contain only the modified files (incremental backup), so if you clean up old ones, your backup/copy won't be complete anymore!

Upvotes: 1

Related Questions