Articles

Copy and rename with a batch script

December 27, 2006 at 11:17:15
Specs: XP Pro SP 2, 2 gigs

I am going to create a batch file and put it in the send to folder. Users are going to right click on excel files and send to this batch file which will copy the file and place in a network drive and append the date to it. I know it sounds crazy but I do not want users to do this on their own.


See More: Copy and rename with a batch script

Report •


#1
December 28, 2006 at 02:40:11

I assume you mean to append the date to the filename, not the extension.

Try the BAT below. It's hardwired to copy to n:\data so you'll want to tailor it to your drive/directory.

::== datedata.bat

@echo off
setLocal EnableDelayedExpansion
call :sub1
for %%A in (%1) do (
copy %%A n:\data\%%~nA%YYYY%%MM%%DD%%%~xA
)

:sub1

:: get sys YMD into vars
@echo off

:: YYYY getter
> syyyy.d echo a 100
>> syyyy.d echo mov ah,2a
>> syyyy.d echo int 21
>> syyyy.d echo.
>> syyyy.d echo p=100 2
>> syyyy.d echo n sizeYYYY
>> syyyy.d echo w
>> syyyy.d echo q
debug < syyyy.d > nul
:: OK

:: MM getter
> sMM.d echo a 100
>> sMM.d echo mov ah,2a
>> sMM.d echo int 21
>> sMM.d echo mov cx,0
>> sMM.d echo mov cl,dh
>> sMM.d echo.
>> sMM.d echo p=100 4
>> sMM.d echo n sizeMM
>> sMM.d echo w
>> sMM.d echo q
debug < sMM.d > nul
:: OK

:: DD getter
> sDD.d echo a 100
>> sDD.d echo mov ah,2a
>> sDD.d echo int 21
>> sDD.d echo mov cx,0
>> sDD.d echo mov cl,dl
>> sDD.d echo.
>> sDD.d echo p=100 4
>> sDD.d echo n sizeDD
>> sDD.d echo w
>> sDD.d echo q
debug < sDD.d > nul
:: OK
del *.d

for %%F in (sizeYYYY sizeMM sizeDD) do call :sub1 %%F
set /p YYYY=<sizeYYYY.#
set /p MM=<sizeMM.#
if %MM% LSS 10 set MM=0%MM%
set /p DD=<sizeDD.#
if %DD% LSS 10 set DD=0%DD%
del size*.*
goto :eof

:sub1
> %1.# echo %~z1
goto :eof

:: DONE


=====================================
If at first you don't succeed, you're about average.

M2



Report •

#2
December 28, 2006 at 04:43:12

Thanks a lot for the code, its great. Two questions for you. Is there a way to have files that have spaces in the file name still work? Also, is there a way to have the time in the file name as well, right after the date?

Report •

#3
December 28, 2006 at 05:07:39

I'll give it a go, but it looks pretty messy.



=====================================
If at first you don't succeed, you're about average.

M2



Report •

Related Solutions

#4
December 28, 2006 at 06:35:04

M2, what I am worried about is users still copying files in over the older ones. Would it be easier to setup a counter for this? to have a counter start after the date in the filename. Like 01, 02, ...

Report •

#5
December 28, 2006 at 07:09:01

I think I can hook up the time stamp.

Do this:

echo %TIME%>time.txt

and paste in the contents of time.txt, sp I know your layout.

Using filenames with spaces may prove to be a real bear.


=====================================
If at first you don't succeed, you're about average.

M2



Report •

#6
December 28, 2006 at 07:15:35

Here is what I got:

10:14:46.74

EST


Report •

#7
December 28, 2006 at 10:48:56

This will append the tine:

::== M5.bat
@echo off
::setLocal EnableDelayedExpansion
call :sub0
for %%A in (%1) do (
copy "%%A" "n:\data\%%~nA%YYYY%%MM%%DD%%TIME:~0,2%%TIME:~3,2%%%~xA"
)
goto :eof

:sub0

:: get sys YMD into vars

@echo off

:: YYYY getter
> syyyy.d echo a 100
>> syyyy.d echo mov ah,2a
>> syyyy.d echo int 21
>> syyyy.d echo.
>> syyyy.d echo p=100 2
>> syyyy.d echo n sizeYYYY
>> syyyy.d echo w
>> syyyy.d echo q
debug < syyyy.d > nul
:: OK

:: MM getter
> sMM.d echo a 100
>> sMM.d echo mov ah,2a
>> sMM.d echo int 21
>> sMM.d echo mov cx,0
>> sMM.d echo mov cl,dh
>> sMM.d echo.
>> sMM.d echo p=100 4
>> sMM.d echo n sizeMM
>> sMM.d echo w
>> sMM.d echo q
debug < sMM.d > nul
:: OK

:: DD getter
> sDD.d echo a 100
>> sDD.d echo mov ah,2a
>> sDD.d echo int 21
>> sDD.d echo mov cx,0
>> sDD.d echo mov cl,dl
>> sDD.d echo.
>> sDD.d echo p=100 4
>> sDD.d echo n sizeDD
>> sDD.d echo w
>> sDD.d echo q
debug < sDD.d > nul
:: OK
del *.d

for %%F in (sizeYYYY sizeMM sizeDD) do call :sub1 %%F
set /p YYYY=<sizeYYYY.#
set /p MM=<sizeMM.#
if %MM% LSS 10 set MM=0%MM%
set /p DD=<sizeDD.#
if %DD% LSS 10 set DD=0%DD%
del size*.*
::echo YYYYMMDD=%YYYY%%MM%%DD%
goto :eof

:sub1
> %1.# echo %~z1
goto :eof


=====================================
If at first you don't succeed, you're about average.

M2



Report •

#8
December 28, 2006 at 11:00:43

Thats great, thanks man. I was thinking about spaces in filenames and I was wondering if you think it is a good idea to have a script first remove the spaces then call this batch file. Do you think this would work?

Report •

#9
December 28, 2006 at 11:17:20

That's a good idea. I'll check it out.


=====================================
If at first you don't succeed, you're about average.

M2



Report •

#10
December 29, 2006 at 06:39:31

Hi mitchell311 and M2,

the following slightly modified "incipit" of the batch solves the space problem by replacing blanks with underscores

@Echo Off
SetLocal EnableDelayedExpansion
Set NoSpace=%*
Set NoSpace=%NoSpace: =_%
Call :sub1
For %%A in (%NoSpace%) Do (
......


Report •

#11
December 29, 2006 at 06:51:51

IVO

I have put the following script in and nothing happens. I am missing something?
Thanks for the help


Report •

#12
December 29, 2006 at 13:49:07

The code I posted is not a new script, just a variant of the M2's batch where two lines are added at the beginning

Set NoSpace=%*
Set NoSpace=%NoSpace: =_%

(i.e. %NoSpace:<blank>=<underscore>%)
and the NoSpace variable used instead of %1 in the For clause.

That replaces the batch command's tail blanks with underscores, i.e. (assumed the script is X.bat)

X My file name.xls becomes My_file_name.xls in the body of the script.

I tested it and the code worked fine, but you have to run the whole M2 script with the above fixes not just the code I posted.


Report •

#13
January 2, 2007 at 05:59:29

IVO
Thats what I did and still no luck. I am posting the code and if you can see anything let me know. Thanks

@echo off
::setLocal EnableDelayedExpansion
::set NoSpace=%*
::set NoSpace=%NoSpace: =_%
call :sub0
for %%A in (%NoSpace%) do (
copy "%%A" "C:\%%~nA_%YYYY%%MM%%DD%_%TIME:~0,2%%TIME:~3,2%%%~xA"
)
goto :eof

:sub0

:: get sys YMD into vars

@echo off

:: YYYY getter
> syyyy.d echo a 100
>> syyyy.d echo mov ah,2a
>> syyyy.d echo int 21
>> syyyy.d echo.
>> syyyy.d echo p=100 2
>> syyyy.d echo n sizeYYYY
>> syyyy.d echo w
>> syyyy.d echo q
debug < syyyy.d > nul
:: OK

:: MM getter
> sMM.d echo a 100
>> sMM.d echo mov ah,2a
>> sMM.d echo int 21
>> sMM.d echo mov cx,0
>> sMM.d echo mov cl,dh
>> sMM.d echo.
>> sMM.d echo p=100 4
>> sMM.d echo n sizeMM
>> sMM.d echo w
>> sMM.d echo q
debug < sMM.d > nul
:: OK

:: DD getter
> sDD.d echo a 100
>> sDD.d echo mov ah,2a
>> sDD.d echo int 21
>> sDD.d echo mov cx,0
>> sDD.d echo mov cl,dl
>> sDD.d echo.
>> sDD.d echo p=100 4
>> sDD.d echo n sizeDD
>> sDD.d echo w
>> sDD.d echo q
debug < sDD.d > nul
:: OK
del *.d

for %%F in (sizeYYYY sizeMM sizeDD) do call :sub1 %%F
set /p YYYY=<sizeYYYY.#
set /p MM=<sizeMM.#
if %MM% LSS 10 set MM=0%MM%
set /p DD=<sizeDD.#
if %DD% LSS 10 set DD=0%DD%
del size*.*
::echo YYYYMMDD=%YYYY%%MM%%DD%
goto :eof

:sub1
> %1.# echo %~z1
goto :eof


Report •

#14
January 2, 2007 at 08:24:27

For atarters, any line beginning with :: does nothing. Beyond that I need to figure out where IVO's lines belong. I'll work on it.


=====================================
If at first you don't succeed, you're about average.

M2



Report •

#15
January 2, 2007 at 12:23:46

Hi mitchell311,

as M2 says if you code

::setLocal EnableDelayedExpansion
::set NoSpace=%*
::set NoSpace=%NoSpace: =_%

the above lines are interpreted as comments and no action is performed (i.e. the NoSpace variable is not set to the command's tail and so on...).

So please, specify if what you posted is the code you actually run or the :: were added for some unspecified reason after test performed.


Report •

#16
January 2, 2007 at 12:42:08

Here is the code I am using. It works with file names that have no spaces but once there is a space in a file name, nothing happens. Thanks for you help guys.

@echo off
setLocal EnableDelayedExpansion
set NoSpace=%*
set NoSpace=%NoSpace: =_%
call :sub0
for %%A in (%NoSpace%) do (
copy "%%A" "C:\%%~nA_%YYYY%%MM%%DD%_%TIME:~0,2%%TIME:~3,2%%%~xA"
)
goto :eof

:sub0

:: get sys YMD into vars

@echo off

:: YYYY getter
> syyyy.d echo a 100
>> syyyy.d echo mov ah,2a
>> syyyy.d echo int 21
>> syyyy.d echo.
>> syyyy.d echo p=100 2
>> syyyy.d echo n sizeYYYY
>> syyyy.d echo w
>> syyyy.d echo q
debug < syyyy.d > nul
:: OK

:: MM getter
> sMM.d echo a 100
>> sMM.d echo mov ah,2a
>> sMM.d echo int 21
>> sMM.d echo mov cx,0
>> sMM.d echo mov cl,dh
>> sMM.d echo.
>> sMM.d echo p=100 4
>> sMM.d echo n sizeMM
>> sMM.d echo w
>> sMM.d echo q
debug < sMM.d > nul
:: OK

:: DD getter
> sDD.d echo a 100
>> sDD.d echo mov ah,2a
>> sDD.d echo int 21
>> sDD.d echo mov cx,0
>> sDD.d echo mov cl,dl
>> sDD.d echo.
>> sDD.d echo p=100 4
>> sDD.d echo n sizeDD
>> sDD.d echo w
>> sDD.d echo q
debug < sDD.d > nul
:: OK
del *.d

for %%F in (sizeYYYY sizeMM sizeDD) do call :sub1 %%F
set /p YYYY=<sizeYYYY.#
set /p MM=<sizeMM.#
if %MM% LSS 10 set MM=0%MM%
set /p DD=<sizeDD.#
if %DD% LSS 10 set DD=0%DD%
del size*.*
::echo YYYYMMDD=%YYYY%%MM%%DD%
goto :eof

:sub1
> %1.# echo %~z1
goto :eof


Report •

#17
January 2, 2007 at 13:21:45

FOUND!

Replace the following line

Copy "%%A"...

with

Copy "%*"...

and you are done... I hope...


Report •

#18
January 3, 2007 at 04:32:44

IVO

I change that and it still works with one word file names and any filenames that have spaces I get this error:
The system cannot find the file specified.

I even tried changed the %%A in this line to %* and had no luck.

for %%A in (%NoSpace%) do (



Report •

#19
January 3, 2007 at 06:22:07

Please add Echo in front of Copy "%*" and report the echoed line and the filename you are processing. The For statement is right with %%A.

Later I'll invetigate what you post as now I have to leave.

Thanks and sorry if I'm wasting your time.


Report •

#20
January 3, 2007 at 06:41:40

IVO, here is what I get. You are not wasting my time at all. Thanks for the help.


for %A in ("C:\test\test_copy.xls") do (
copy "C:\test\test copy.xls" "C:\%~nA_20070103_ 937%~xA"


Report •

#21
January 3, 2007 at 12:16:42

OK, Houston to mitchell311... try this

For %%A in (%*) Do (
Copy %* "C\%%~nA...

Report what you get, there are other shots on the gun if tht fails. (beware to set the double % in front of the ~)


Report •

#22
January 3, 2007 at 12:45:01

IVO

Save the shots, we are good. You guys are good.

IVO and M2, Thank you very much for all the help.


Report •

#23
January 3, 2007 at 14:08:33

Please post final version.


=====================================
If at first you don't succeed, you're about average.

M2



Report •

#24
January 3, 2007 at 14:35:32

Hi M2,

the final version is just

@Echo Off
Call :sub0
For %%A in (%*) Do (
Copy %* "C:\%%~nA_%YYYY%%MM%%DD%_%TIME:~0,2%%TIME:~3,2%%%~xA"
)
GoTo :EOF

:sub0

........

Note that the filename on the command's tail is embraced by " (i.e. "My File Name.xls").

The above version allowed mitchell311 to fly to the moon.


Report •

#25
January 4, 2007 at 02:25:04

Hi IVO,

I had to modify it top this:

::===========================
@Echo Off
For %%A in ("%*") Do (
echo Copy "%*" "C:\%%~nA_%YYYY%%MM%%DD%_%TIME:~0,2%%TIME:~3,2%%%~xA"
)
==================================

The one you posted gave me this:

C:\temp\-\rendate>fin test two.txt
Copy test two.txt "C:\test__1721"
Copy test two.txt "C:\two__1721.txt"
=========================================
I've really lost the plot on this one.

Yet another reason that LFNs should be left for a real OS, ie unix.



=====================================
If at first you don't succeed, you're about average.

M2



Report •

#26
January 4, 2007 at 08:05:26

Here is the final version that works:

---------------
@echo off
setLocal EnableDelayedExpansion
set NoSpace=%*
set NoSpace=%NoSpace: =_%
call :sub0
for %%A in (%*) do (
copy %* "C:\%%~nA_%YYYY%%MM%%DD%_%TIME:~0,2%%TIME:~3,2%%%~xA"
)
goto :eof

:sub0

:: get sys YMD into vars

@echo off

:: YYYY getter
> syyyy.d echo a 100
>> syyyy.d echo mov ah,2a
>> syyyy.d echo int 21
>> syyyy.d echo.
>> syyyy.d echo p=100 2
>> syyyy.d echo n sizeYYYY
>> syyyy.d echo w
>> syyyy.d echo q
debug < syyyy.d > nul
:: OK

:: MM getter
> sMM.d echo a 100
>> sMM.d echo mov ah,2a
>> sMM.d echo int 21
>> sMM.d echo mov cx,0
>> sMM.d echo mov cl,dh
>> sMM.d echo.
>> sMM.d echo p=100 4
>> sMM.d echo n sizeMM
>> sMM.d echo w
>> sMM.d echo q
debug < sMM.d > nul
:: OK

:: DD getter
> sDD.d echo a 100
>> sDD.d echo mov ah,2a
>> sDD.d echo int 21
>> sDD.d echo mov cx,0
>> sDD.d echo mov cl,dl
>> sDD.d echo.
>> sDD.d echo p=100 4
>> sDD.d echo n sizeDD
>> sDD.d echo w
>> sDD.d echo q
debug < sDD.d > nul
:: OK
del *.d

for %%F in (sizeYYYY sizeMM sizeDD) do call :sub1 %%F
set /p YYYY=<sizeYYYY.#
set /p MM=<sizeMM.#
if %MM% LSS 10 set MM=0%MM%
set /p DD=<sizeDD.#
if %DD% LSS 10 set DD=0%DD%
del size*.*
::echo YYYYMMDD=%YYYY%%MM%%DD%
goto :eof

:sub1
> %1.# echo %~z1
goto :eof


---------------


Report •

#27
January 5, 2007 at 03:03:32

Hi M2 and mitchell311,

To explain why the *correct* ultimate version is what I posted run the following sample batch

@Echo Off
Echo FileName is %*
For %%A in (%*) Do (Echo n=%%~nA x=%%~xA)

assumed the batch's name is X.bat, type

X My File Name.xls

then

X "My File Name.xls"

You see without doubts that parsing a variable embraced by " leads to the correct ultimate components.

The above sample suggests an exciting way to manipulate LFNs in batches, while indeed quite complex as nuclear physics is compared to ordinay mechanics.


Report •

#28
January 9, 2007 at 09:48:11

Sorry to ask you guys another question.

Is there a way to set this up so I can copy multiple files to this and not just one?


Report •


Ask Question