Jump to content

Batch File copy and rename with date


Recommended Posts

Hi

I am trying to write a batch file that will copy a file from one network drive to another and rename it on the new location so the filename has the date at the end.

Below is what I have so far but this is not working. It hits problems with files that have spaces in them, sometimes returns the error 'NET is not a valid command' and does not wait until the file is finished copying before moving on to the next command.

I can also only get the date added to the begining of the file when ideally I need it at the end.


@@echo off
REM Fetch the file name from the command line
SET FILENAME=%2
SET DTS=%1
net use \\llsvr-bur-3330\d$ /USER:DOMAIN\username password
net use \\llsvr-bur-3333\e$ /USER:DOMAIN\username password

REM Create the date and time elements.
For /f "tokens=1-7 delims=:/-, " %%i in ('echo exit^|cmd /q /k"prompt $D $T"') do (
For /f "tokens=2-4 delims=/-,() skip=1" %%a in ('echo.^|date') do (
set dd=%%i
set mm=%%j
set yy=%%k
set hh=%%l
set min=%%m
set ss=%%n
)
)


REM COPY FILE AND RENAME WITH DATE AND TIME APPENDED

SET NEW_FILE=%dd%-%mm%-%yy%_%hh%%min%_%NAME%
START /WAIT /B COPY /V %NAME% %NEW_FILE%

CALL CUBESWAP.bat

Could someone possibly give me some help sorting this out please? Sorry if this seems like a bit of a hopeless attempt, its my first attempt at windows batch files! Thanks in advance for any help.

John

Link to comment
Share on other sites


From the fact that you are using the For /F syntax, I get that you are going to run this in 2K/XP or later OS.

In such cases, it is advised NOT to use the .bat extension but rather the .cmd one, but it is not needed, it's just a way to make sure you won't run it in DOS/9x/Me.

The problem should be only where you "expand" the variables and "pass" them to a command.

The default separator is the space, thus a name that includes a space is seen by the command processor as TWO parameters.

Simply enclose the variables with quotes.

START /WAIT /B COPY /V "%NAME%" "%NEW_FILE%"

This should apply also to "FILENAME" which is given as second parameter when calling the batch.

But I seem to fail seeing the variable "NAME" defined anywhere in the batch, I guess it should be everywhere either "FILENAME" or "NAME". :unsure:

You need to strip the quotes in order to add the date in front of the name, and enclose the date+name in "new" quotes.

SET NEW_FILE="%dd%-%mm%-%yy%_%hh%%min%_%NAME%"

There are several ways to do so, most notably using a CALL with parameter and expanding %~1, or something like SET NAME=%NAME:"=%.

But the line:

START /WAIT /B COPY /V "%NAME%" "%NEW_FILE%"

Won't work correctly as it misses the PATH to both the source and destination files.

Check this site:

http://www.robvanderwoude.com

And these threads:

http://www.msfn.org/board/Rename-File-With...-Fi-t47812.html

http://www.msfn.org/board/index.php?act=idx/showtopic=37572

To see some examples, post again if you need more help.

jaclaz

Link to comment
Share on other sites

From your coded section, I honestly have no idea of your intentions. You're setting two variables using parameters given at script invokation; these are being set to names which aren't used. You have two variables in your script which aren't defined and a nested for loop which isn't used at all.

Apart from that the idea is not very good. If you want to rename using dates etc. the only useful format would be YYYY-MM-DD_hh-mm_filename. The reason for this is that you can sort your files appropriately. Using your current attempted system you could have files ordered thus:

02-05-07_23-14_FileName.ext

06-01-04_09-13_FileName.ext

06-05-08_16-25_FileName.ext

21-07-05_11-06_FileName.ext

27-03-98_03-34_FileName.ext

Instead of
1998-03-27_03-34_FileName.ext

2004-01-06_09-13_FileName.ext

2005-07-21_11-06_FileName.ext

2007-05-02_23-14_FileName.ext

2008-05-06_16-25_FileName.ext

Try looking at what you want again then give us a little bit more pertinent information.

Link to comment
Share on other sites

I think this is what you are looking for. Save this as a bat or cmd file.

@echo off

xcopy /I /E /H d:\ e:\
cd "e:dir of files to be renamed"
for %%i in (*.*) do Call :rename "%%i"


:rename
set oldname=%~1
Set FileDate=%date:/=%
set newname=%FileDate%-%oldname%
ren "%oldname%" "%newname%"

If you dont want the day of the week in your file name change the set newname to this:

set newname=%FileDate:~4%-%oldname%

Edited by Smiley357
Link to comment
Share on other sites

BTW Smiley357, the output of %DATE% is different depending upon locale etc.

For hem352, I'd suggest that %DATE:~4% resolves to 2008 which isn't what I expect you wanted!

Link to comment
Share on other sites

You're setting two variables using parameters given at script invokation; these are being set to names which aren't used.

To clarify, they are used by the cubeswap.bat script called at the end of the script.

You have two variables in your script which aren't defined.

I think there is only one not defined and that was a simple typo where I am having to copy from one screen to another because the machine we are trying to do this on has no access to the web. The variables NAME and FILENAME should be the same thing. Sorry about that.

Apart from that the idea is not very good. If you want to rename using dates etc. the only useful format would be YYYY-MM-DD_hh-mm_filename. The reason for this is that you can sort your files appropriately. Using your current attempted system you could have files ordered thus:

02-05-07_23-14_FileName.ext

06-01-04_09-13_FileName.ext

06-05-08_16-25_FileName.ext

21-07-05_11-06_FileName.ext

27-03-98_03-34_FileName.ext

Instead of

1998-03-27_03-34_FileName.ext

2004-01-06_09-13_FileName.ext

2005-07-21_11-06_FileName.ext

2007-05-02_23-14_FileName.ext

2008-05-06_16-25_FileName.ext

What I want ideally is the date after the filename but before is the only way I could get this to work. I was hoping someone could explain how I swap these around without messing up the file extension. If the date has to go before then putting year first would make finding a file difficult as over the course of a month we are going to end up with 2400+ files in this directory at any one time. I figured it is easier to find a file amongst 80 with the same day number at the beginning than to try and attempt to find a file amongst 2400+ files all starting with the same year.

Put simply what I want to do is take file A from server A and copy it to server B renaming the copy on server B to be the original filename plus the date of copy. So a file named 'file.txt' on sever A would become 'file_dd-mm-yyyy_hh-mm.txt' on server B.

I then need to pass the fully qualified filename on server B to another script called Cubeswap.bat

I appreciate I have probably made a bit of a mess of this in the first place but as I mentioned its the first time I have ever tried to write a windows batch file and I'd rather 'have a go' before I asked for help.

The idea being, when we get this working is we can use the batch file in a scheduler to automate these copies each night.

Thanks for all the help so far, I'm still working on this so would still welcome more suggestions.

Regards

John

Link to comment
Share on other sites

What I want ideally is the date after the filename but before is the only way I could get this to work. I was hoping someone could explain how I swap these around without messing up the file extension. If the date has to go before then putting year first would make finding a file difficult as over the course of a month we are going to end up with 2400+ files in this directory at any one time. I figured it is easier to find a file amongst 80 with the same day number at the beginning than to try and attempt to find a file amongst 2400+ files all starting with the same year.

You can easily "parse" separately filename and extension, by using the tilde parameters substitution, see this:

http://www.robvanderwoude.com/ntfor.html

In addition, substitution of FOR variable references has been enhanced.

You can now use the following optional syntax:

%~i - expands %i removing any surrounding quotes (")

%~fi - expands %i to a fully qualified path name

%~di - expands %i to a drive letter only

%~pi - expands %i to a path only

%~ni - expands %i to a file name only

%~xi - expands %i to a file extension only

%~si - expanded path contains short names only

%~ai - expands %i to file attributes of file

%~ti - expands %i to date/time of file

%~zi - expands %i to size of file

The above works also for variables passed by CALL functions.

Something like this:

@ECHO OFF
SET file1="C:\foo withspace\foo.txt"
CALL :PARSEVAR %file%

FOR %%A IN ( file1 fullname fullpath drive filename fileext firstpart addedpart newfile) DO SET %%A

GOTO :EOF

:PARSEVAR
SET fullname=%~1
SET fullpath=%~f1
SET drive=%~d1
SET filename=%~n1
SET fileext=%~x1
SET firstpart=%~dpn1
SET addedpart=test
SET newfile="%firstpart%%addedpart%%fileext%"
GOTO :EOF

Should give you the idea.

jaclaz

Link to comment
Share on other sites

can you just make folders with the date in instead?

this is what i'd do..

for this example "D:\files" is the source folder and "E:\files" is desination

set CURRDATE=%DATE:/=-%

md "E:\files\%currdate%"

xcopy /e /h /y D:\files\*.* "E:\files\%currdate%\"

that would create e:\Files\07-05-2008\

or similar..

Link to comment
Share on other sites

can you just make folders with the date in instead?

No unfortuantely not, the application that uses the created files insists that they appear in one location only, it can only point to one directory.

John

Link to comment
Share on other sites

%~i - expands %i removing any surrounding quotes (")

%~fi - expands %i to a fully qualified path name

%~di - expands %i to a drive letter only

%~pi - expands %i to a path only

%~ni - expands %i to a file name only

%~xi - expands %i to a file extension only

%~si - expanded path contains short names only

%~ai - expands %i to file attributes of file

%~ti - expands %i to date/time of file

%~zi - expands %i to size of file

Thank you for this very valuable info Jaclaz, very much appreciated, I'm sure I can work with this.

John

Link to comment
Share on other sites

It’s all about string manipulation. Just change this line. I know this batch file changes every file in a directory but you have the function that does all the work. Just pass the file name to the function and you are good to go.

set newname=%oldname:~0,-4%-%FileDate%%oldname:~-4%

Edited by Yzöwl
fixed codebox size!
Link to comment
Share on other sites

It’s all about string manipulation. Just change this line. I know this batch file changes every file in a directory but you have the function that does all the work. Just pass the file name to the function and you are good to go.

set newname=%oldname:~0,-4%-%FileDate%%oldname:~-4%

If I may, NO.

The "4" parameter implies that every file has been named conforming to a (non existing) N+3 convention, i.e. ALL files need to have an extension and the extension MUST be exactly three characters long.

This is not the case always, and expecially nowadays, with the new extensions the good guys at MS invented for Office files:

http://en.wikipedia.org/wiki/Microsoft_Off...file_extensions

it is (or will be VERY common to have files with four or five characters extensions)

The internal filenames parsing of the tilde expansion uses the dot as separator between filename and its extension and it works with any length of the extension.

This can be replicated by parsing the variables and finding the position of the dot, but it is unneeded, as the above method works perfectly.

jaclaz

Link to comment
Share on other sites

Thanks to everyone for their help, especially Jaclaz, I now have a working script but.....

Is there a way to make the script wait for a file copy to complete before continuing? Some of the files I am using this to copy are rather big and cant take 10 minutes or so to copy.

Is there a way to get just the just the files parent directory into a variable? For example if a file is in directory c:\dir1\dir2\dir3\file is it possible to set a variable to just contain whatever dir3 may be?

Thanks again to everyone for your help. It really is greatly appreciated.

Regards

John

Link to comment
Share on other sites

I am not sure I understand what you are asking for.

Waiting for the completion of a filecopy process should be default.

Why don't you post your batch at the point it is now, so that we can have a look at it and maybe show you what needs to be added?

A check for ERRORLEVEL:

http://www.robvanderwoude.com/errorlevel.html

may be used, starting a second batch and checking for it's termination, or using directly something like:

start /wait cmd.exe /c call anotherbatch.cmd param1 param2

Getting just the name of last-in-tree "parent" directory should be possible parsing the %~p1 variable, using a FOR loop using the backslash as delimiter, but what is it needed for? :unsure:

jaclaz

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...