# DOS First in first out back up .bat



## Whatistheinternet (May 19, 2010)

I am trying to make a first in first out back up script. This is what I have come up with, I think it is ugly is there any way to clean it up? Any pointers? Thanks 

```
cd\ 
    del "C:\Documents and Settings\N\Desktop\Source\yay i did it5.jpg" 
    rename "C:\Documents and Settings\N\Desktop\Source\yay i did it4.jpg" "yay i did it5.jpg" 
    rename "C:\Documents and Settings\N\Desktop\Source\yay i did it3.jpg" "yay i did it4.jpg" 
    rename "C:\Documents and Settings\N\Desktop\Source\yay i did it2.jpg" "yay i did it3.jpg" 
    rename "C:\Documents and Settings\N\Desktop\Source\yay i did it1.jpg" "yay i did it2.jpg" 
    rename "C:\Documents and Settings\N\Desktop\Source\yay i did it.jpg" "yay i did it1.jpg" 
    xcopy /V /C /Y /E "C:\Documents and Settings\N\Desktop\Source2\yay i did it.jpg" "C:\Documents and                Settings\N\esktop\source"
```


----------



## TheOutcaste (Aug 8, 2007)

Welcome to TSG!
If you use a variable for the paths it will look a little cleaner, plus helps prevent typos like the missing D in Desktop in the last line.
The Xcopy switches can all be combined as one switch.
If any of the versions don't exist in the destination folder, you'll get a error. You can avoid that using an If Exist statment:

```
cd\
Set _Source=C:\Documents and Settings\N\Desktop\Source2
Set _Dest=C:\Documents and Settings\N\Desktop\Source
If Exist "%_Dest%\yay i did it5.jpg" del "%_Dest%\yay i did it5.jpg"
If Exist "%_Dest%\yay i did it4.jpg" rename "%_Dest%\yay i did it4.jpg" "yay i did it5.jpg"
If Exist "%_Dest%\yay i did it3.jpg" rename "%_Dest%\yay i did it3.jpg" "yay i did it4.jpg"
If Exist "%_Dest%\yay i did it2.jpg" rename "%_Dest%\yay i did it2.jpg" "yay i did it3.jpg"
If Exist "%_Dest%\yay i did it1.jpg" rename "%_Dest%\yay i did it1.jpg" "yay i did it2.jpg"
If Exist "%_Dest%\yay i did it.jpg" rename "%_Dest%\yay i did it.jpg" "yay i did it1.jpg"
xcopy /CEVY "%_Source%\yay i did it.jpg" "%_Dest%\"
```
Here's my version. This will only copy files that don't exist in the destination, or that have changed since the backup script was last run. This means that files with the same version number were not necessarily copied at the same time. If you are wanting to create a snapshot type backup, it's much easier to just used a dated backup folder, rather than adding version numbers to files.

It does not copy hidden or system files. Add the /H switch to the Xcopy commands to include them
You can keep any number of versions up to 9999. Version numbers added to files names are padded with leading zeros so they are always 4 digits in length so they will sort nicely.


```
@Echo Off
SetLocal EnableDelayedExpansion
Set _SourceDir=C:\Test Source
Set _DestDir=C:\Test Dest
Set _Max=10
:::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Do not Edit below this line
:::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Pad version numbers so they are 4 digit
Set _PadStr=000
Set _Pad=4
If %_Max% GTR 9999 Goto _Error
Set _Last=%_PadStr%%_Max%
:: Subtract one to use in loop
Set /A _Max-=1
Call Set _Last=%%_Last:~-%_Pad%%%
:: Get list of files to copy. Only copy files that have changed, or don't exist in Destination Directory
Xcopy "%_SourceDir%" "%_DestDir%" /CDELY |Findstr /I /V "file(s)">"%Temp%\CopyList.txt"
:: If Length of list is zero, nothing to copy
For %%I In ("%temp%\CopyList.txt") Do If %%~zI==0 Goto :_Cleanup
For /F "Tokens=* Delims=" %%I in ('Type "%Temp%\CopyList.txt"') Do (
  Call :_RPath "%%~dpI" "%_SourceDir%"
  :: Delete Highest version if it exists
  If Exist "!_DestPath!%%~nI-%_Last%%%~xI" Del "!_DestPath!%%~nI-%_Last%%%~xI"
  :: Rename all versions by incrementing by 1
  For /L %%N In (%_Max%,-1,1) Do (
    Set /A _Inc1=%%N+1
    Set _Inc0=%_PadStr%%%N
    Set _Inc1=%_PadStr%!_Inc1!
    Call Set _Inc0=%%_Inc0:~-%_Pad%%%
    Call Set _Inc1=%%_Inc1:~-%_Pad%%%
    If Exist "!_DestPath!%%~nI-!_Inc0!%%~xI" Ren "!_DestPath!%%~nI-!_Inc0!%%~xI" "%%~nI-!_Inc1!%%~xI"
  )
  :: Add version number to first file
  If Exist "!_DestPath!%%~nxI" Ren "!_DestPath!%%~nxI" "%%~nI-!_Inc0!%%~xI"
  :: Copy the file
  Xcopy /CDVY "%%I" "!_DestPath!">Nul
)
:_Cleanup
Del "%Temp%\CopyList.txt"
Goto :EOF
::::::::::::::::::::::::::::::::::::::::::::::::::::::
::           Subroutines
::::::::::::::::::::::::::::::::::::::::::::::::::::::
:_Error
Echo.Max number to keep set too High. Must be less than %_Div%
Goto :EOF
::::::::::::::::::::::::::::::::::::::::::::::::::::::
:_RPath
:: Replaces Source root folder with Destination root folder path
Set _CurPath=%~1
Set _RelPath=!_CurPath:%~2=!
Set _DestPath=%_DestDir%%_RelPath%
```


----------



## Whatistheinternet (May 19, 2010)

Oh boy, all that is way over my head haha, i'm am not familiar with the variables and such you are using, so i'm going to do some research and get back to you with a response! Thank you so much tho for the reply, that looks like some code you got there. Maybe you could break it down a little bit for me? Thanks outcaste!!


----------



## Whatistheinternet (May 19, 2010)

Ok, so I did a little research on the different variable and cmds you used. I took you script and hacked it up a bit to try and fit it to my purpose. Basically I now need to do the same thing but with a whole folder. So in program files>Palm>Dlavi I need the Dlavi folder and its contents copied over to another folder in program files called palmbup. This is batch I used:


```
cd\
Set _Source=C:\Documents and Settings\NSpiekerman\Desktop\progfile\Palm\DLavi
Set _Dest=C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup
If Exist "%_Dest%\dlavi5" rd "%_Dest%\dlavi5"
If Exist "%_Dest%\dlavi4" rename "%_Dest%\dlavi4" "dlavi5"
If Exist "%_Dest%\dlavi3" rename "%_Dest%\dlavi3" "dlavi4"
If Exist "%_Dest%\dlavi2" rename "%_Dest%\dlavi2" "dlavi3"
If Exist "%_Dest%\dlavi1" rename "%_Dest%\dlavi1" "dlavi2"
If Exist "%_Dest%\dlavi" rename "%_Dest%\dlavi" "dlavi1"
xcopy /CEVY "%_Source%\dlavi" "%_Dest%\"
```
I get the following errors. What is it i'm doing wrong.

C:\>"C:\Documents and Settings\NSpiekerman\Desktop\palmbup.cmd"

C:\>cd\

C:\>Set _Source=C:\Documents and Settings\NSpiekerman\Desktop\progfile\Palm\DLav
i

C:\>Set _Dest=C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup

C:\>If Exist "C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup\dla
vi5" rd "C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup\dlavi5"

The directory is not empty.

C:\>If Exist "C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup\dla
vi4" rename "C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup\dlav
i4" "dlavi5"
A duplicate file name exists, or the file
cannot be found.

C:\>If Exist "C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup\dla
vi3" rename "C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup\dlav
i3" "dlavi4"
A duplicate file name exists, or the file
cannot be found.

C:\>If Exist "C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup\dla
vi2" rename "C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup\dlav
i2" "dlavi3"
A duplicate file name exists, or the file
cannot be found.

C:\>If Exist "C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup\dla
vi1" rename "C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup\dlav
i1" "dlavi2"
A duplicate file name exists, or the file
cannot be found.

C:\>If Exist "C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup\dla
vi" rename "C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup\dlavi
" "dlavi1"
A duplicate file name exists, or the file
cannot be found.

C:\>xcopy /CEVY "C:\Documents and Settings\NSpiekerman\Desktop\progfile\Palm\DLa
vi\dlavi" "C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup\"
File not found - dlavi
0 File(s) copied
I have the switches to overwrite, but it's not doing that. What am I doing wrong! Thanks for the help


----------



## TheOutcaste (Aug 8, 2007)

Whatistheinternet said:


> If Exist "C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup\dla
> vi5" rd "C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup\dlavi5"
> 
> The directory is not empty.


This is the one causing all the problems. If the directory doesn't get removed, all of the rename operations will fail.
Removing a directory can only be done if it's empty, unless you use the */S* switch (means process *S*ubdirectories as well). You then need to use */Q* (*Q*uiet mode) so it won't prompt for permission to remove a directory that isn't empty. So change that one line and add the switches:

```
If Exist "%_Dest%\dlavi5" rd [COLOR=Red][B]/Q /S[/B][/COLOR] "%_Dest%\dlavi5"
```
This would be the snapshot type backup I was referring to, just using numbers 1-5 instead of a date. Much easier to implement and use, as you don't have to rename files when restoring an older version. Each folder is a full backup, so uses the most disk space.

Adding a verson number to the files and storing them in the same folder uses less space, as a file is only copied if it's changed Being in the same folder lets you see if there are other versions of a file without having to look in different folder's, but does require you to rename the file before restoring. Files with the same version number might not be from the same time period, you have to look at the creation date. No "right way", just depends on how you want to use it, and if disk space is a concern.

I'll post a breakdown of the ealier code later on when I have time to write it up.


----------



## Whatistheinternet (May 19, 2010)

using this code with your suggestions of switches

```
cd\
Set _Source="C:\Documents and Settings\NSpiekerman\Desktop\progfile\Palm\DLavi"
Set _Dest="C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup"
If Exist "%_Dest%\dlavi5" rd /Q /S "%_Dest%\dlavi5"
If Exist "%_Dest%\dlavi4" rename "%_Dest%\dlavi4" "dlavi5"
If Exist "%_Dest%\dlavi3" rename "%_Dest%\dlavi3" "dlavi4"
If Exist "%_Dest%\dlavi2" rename "%_Dest%\dlavi2" "dlavi3"
If Exist "%_Dest%\dlavi1" rename "%_Dest%\dlavi1" "dlavi2"
If Exist "%_Dest%\dlavi" rename "%_Dest%\dlavi" "dlavi1"
xcopy /CEVY "%_Source%\dlavi" "%_Dest%\"
```
I get this:

C:\Documents and Settings\NSpiekerman>"C:\Documents and Settings\NSpiekerman\Des
ktop\palmbup.cmd"

C:\Documents and Settings\NSpiekerman>cd\

C:\>Set _Source="C:\Documents and Settings\NSpiekerman\Desktop\progfile\Palm\DLa
vi"

C:\>Set _Dest="C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup"

C:\>If Exist ""C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup"\d
lavi5" rd /Q /S ""C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup
"\dlavi5"

C:\>If Exist ""C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup"\d
lavi4" rename ""C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup"\
dlavi4" "dlavi5"

C:\>If Exist ""C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup"\d
lavi3" rename ""C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup"\
dlavi3" "dlavi4"

C:\>If Exist ""C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup"\d
lavi2" rename ""C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup"\
dlavi2" "dlavi3"

C:\>If Exist ""C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup"\d
lavi1" rename ""C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup"\
dlavi1" "dlavi2"

C:\>If Exist ""C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup"\d
lavi" rename ""C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup"\d
lavi" "dlavi1"

C:\>xcopy /CEVY ""C:\Documents and Settings\NSpiekerman\Desktop\progfile\Palm\DL
avi"\dlavi" "C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup"\"

Invalid number of parameters

Am I not using the right switches? I Appreciate the help the outcaste.


----------



## TheOutcaste (Aug 8, 2007)

It's the quotes that are causing the problem, you used quotes when you defined the variables, then used quotes again around the variables, causing them to be doubled. Rename seems to work ok with it, but Xcopy doesn't.
Not quite sure how this line is being interpreted, I would expect two double quotes at the start of the Destination folder but there is only one. In any case, it's seeing more parameters than just the source and destination because of the way it is parsing the quotes.
Solution is to remove the quotes from the variable definition lines (*Set _Source=* and *Set _Dest=*) and just quote the variables.
Another tip, you can use the UserProfile variable so it will get the path for the current user, makes it easier to use in a different user account

```
cd\
Set _Source=%UserProfile%\Desktop\progfile\Palm\DLavi
Set _Dest=%UserProfile%\Desktop\progfile\PalmBup
If Exist "%_Dest%\dlavi5" rd /Q /S "%_Dest%\dlavi5"
If Exist "%_Dest%\dlavi4" rename "%_Dest%\dlavi4" "dlavi5"
If Exist "%_Dest%\dlavi3" rename "%_Dest%\dlavi3" "dlavi4"
If Exist "%_Dest%\dlavi2" rename "%_Dest%\dlavi2" "dlavi3"
If Exist "%_Dest%\dlavi1" rename "%_Dest%\dlavi1" "dlavi2"
If Exist "%_Dest%\dlavi" rename "%_Dest%\dlavi" "dlavi1"
xcopy /CEVY "%_Source%\dlavi" "%_Dest%\"
```


----------



## TheOutcaste (Aug 8, 2007)

Here's a line by line breakdown of the code. If you don't have an editor that displays line numbers, I highly recommend Notepad++:

```
01 - Turns off Echo so Commands won't display
02 - Turns on Delayed Variable Expansion and declares a local environment space
03 - Set's Source folder path variable
04 - Set's Destination folder path variable
05 - Set's number of previous versions to keep in addition to the current version. For this discussion, assume it's 5
06 - Comment
07 - Comment
08 - Comment
09 - Comment
10 - String used to add leading zeros for padding version numbers
11 - Number of digits to use for the version numbers
12 - Check if the MAX value is larger than the number of digits specified
13 - Set's the variable Last to the padded MAX number
14 - Comment
15 - Subtract one from max to use in the Rename loop
16 - Set length of the MAX version number by extracting the right most characters. Call is used so the _Pad variable can be used. Using Delayed Expansion also works
17 - Comment
18 - Get a list of the files that will be copied by using Xcopy with the /L switch/. The /D means only files that don't exist in the destination, or that are newer will be listed. This list is saved in a temp file in the Users Temp folder.
19 - Comment
20 - Check the size of the Temp file, if there are no files to copy the program will exit. %%~z modifier is used to get the file length, see FOR /? for info.
21 - Main program section. Each file path/name in the Temp file is read in and processed.
22 - Data is the FQPN (Fully Qualified Path Name) of the Soruce folder, so call this routine to replace the Source path with the Destination path
23 - Comment
24 - If the Destination\FileName-0005.ext file exists, we delete it. Loop modifiers let us get the filename (%%~n) and File Extension (%%~x) to build the name to check
25 - Comment
26 - This loop renames the version files. Loop starts at max-1 (4) counts down to 1
27 - Set a variable to Current number+1, so first time through this will be 5
28 - These lines pad the numbers with the correct number of leading zeros. First add the string of zeros
29 - First add the string of zeros
30 - Extract the last 4 characters
31 - Extract the last 4 characters
32 - Check if the file exists and rename if it does. First time though it's If exist Destination\FileName-0004.ext Rename Destination\FileName-0004.ext FileName-0005.ext
33 - Closing parenthesis for the For loop Line continuation
34 - Comment
35 - Now we rename the original file (FileName.ext) to FileName-0001.ext
36 - Comment
37 - Now we copy the file from the Source to the Destination folder using Xcopy
38 - Closing parenthesis for the For loop Line continuation
39 - Cleanup Label
40 - Delete the Temp file
41 - Exit the program
42 - Comment
43 - Comment
44 - Comment
45 - Error Label
46 - Messsage if MAX number is set too high
47 - Exit the program
48 - Comment
49 - RPath Label
50 - Comment
51 - Sets _Curpath to the Source FQPN and removes the quotes
52 - Removes the Source path root (which is in the second passed variable) from the FQDN, leaving just a relative path
53 - Adds the RElative path to the Destination path root
54 - At end of file, so a Goto :EOF is not needed to return
```


----------



## Whatistheinternet (May 19, 2010)

The outcaste, you have been an amazing help! I wish everyone one the internet was as helpful! Ok so I finally got it to run, kinda, the only problem is:

C:\Documents and Settings\NSpiekerman>cd\

C:\>"C:\Documents and Settings\NSpiekerman\Desktop\caste.cmd" (I've named the script Caste in your honor )

C:\>cd\

C:\>Set _Source=C:\Documents and Settings\NSpiekerman\Desktop\progfile\Palm

C:\>Set _Dest=C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup

C:\>If Exist "C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup\dlavi5" rd /Q /S
"C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup\dlavi5"

C:\>If Exist "C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup\dlavi4" rename "C
:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup\dlavi4" "dlavi5"

C:\>If Exist "C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup\dlavi3" rename "C
:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup\dlavi3" "dlavi4"

C:\>If Exist "C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup\dlavi2" rename "C
:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup\dlavi2" "dlavi3"

C:\>If Exist "C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup\dlavi1" rename "C
:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup\dlavi1" "dlavi2"

C:\>If Exist "C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup\dlavi" rename "C:
\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup\dlavi" "dlavi1"

C:\>xcopy /CEVY "C:\Documents and Settings\NSpiekerman\Desktop\progfile\Palm\dlavi" "C:\Docume
nts and Settings\NSpiekerman\Desktop\progfile\PalmBup\dlavi"
Does C:\Documents and Settings\NSpiekerman\Desktop\progfile\PalmBup\dlavi specify a file name
or directory name on the target
*(F = file, D = directory)? d*
C:\Documents and Settings\NSpiekerman\Desktop\progfile\Palm\dlavi\dlavi\aaa.jpg
C:\Documents and Settings\NSpiekerman\Desktop\progfile\Palm\dlavi\dlavi\aaa1.jpg
C:\Documents and Settings\NSpiekerman\Desktop\progfile\Palm\dlavi\dlavi\aaa2.jpg
C:\Documents and Settings\NSpiekerman\Desktop\progfile\Palm\dlavi\dlavi\aaa3.jpg
C:\Documents and Settings\NSpiekerman\Desktop\progfile\Palm\dlavi\dlavi\aaa4.jpg
C:\Documents and Settings\NSpiekerman\Desktop\progfile\Palm\dlavi\dlavi\aaa5.jpg
6 File(s) copied
Is there a way to suprress that confirmation? this is the code I'm using,


```
cd\
Set _Source=%UserProfile%\Desktop\progfile\Palm
Set _Dest=%UserProfile%\Desktop\progfile\PalmBup
If Exist "%_Dest%\dlavi5" rd /Q /S "%_Dest%\dlavi5"
If Exist "%_Dest%\dlavi4" rename "%_Dest%\dlavi4" "dlavi5"
If Exist "%_Dest%\dlavi3" rename "%_Dest%\dlavi3" "dlavi4"
If Exist "%_Dest%\dlavi2" rename "%_Dest%\dlavi2" "dlavi3"
If Exist "%_Dest%\dlavi1" rename "%_Dest%\dlavi1" "dlavi2"
If Exist "%_Dest%\dlavi" rename "%_Dest%\dlavi" "dlavi1"
xcopy /CEVY "%_Source%\dlavi" "%_Dest%\dlavi"
```


----------



## Whatistheinternet (May 19, 2010)

Hmm I think I found the solution, I used:

```
echo d | xcopy /CEVY "%_Source%\dlavi" "%_Dest%\dlavi"[code/]
```


----------



## TheOutcaste (Aug 8, 2007)

That's happening because you removed the trailing backslash from the Destination folder in the XCopy command.

```
xcopy /CEVY "%_Source%\dlavi" "%_Dest%\dlavi[COLOR=Red][B]\[/B][/COLOR]"
```
If it doesn't end with a backslash, Xcopy doesn't know if it's a file name or a path, and you get that prompt.

Your solution of using Echo to pipe a *d* to Xcopy also works:up:


----------

