Create a Log of a Batch File

I have a batch file that I copied from another site and modified it for the folders I wanted to copy data from and to.  I need some help with the code to put in that will create a log file each day that it runs and have that log file named for the current days date when it runs YYYYMMDD.log.  So if it ran today a log would be created called 20111025.log, tomorrow would be 20111026.log for example.  Below is my current code.  It copys the files with the date modified as the current day and pastes it into another folder.  Thanks for any help.

::Copy Files Made Or Modified Today
@echo off
setlocal
set source=c:\Users\philip\Desktop\Daily
set dest=c:\Users\philip\Desktop\Weekly
pushd "%source%"
set t=%date:~4%
for /f %%a in ('dir /b /a-d /o-d') do call :PROCESS "%%a"
goto :eof
popd

:PROCESS
for /f %%j in ('echo %~t1') do set d=%%j
if "%d%"=="%t%" copy %1 "%dest%"
goto :eof
LVL 4
pagoscheAsked:
Who is Participating?
 
Bill PrewCommented:
@pagosche

Sorry for the delays between my responses, juggling several things this week.

In the task scheduler you can specify more than just the name of the BAT file to be run automatically.  It can include the full command line you want to execute, including any parms to pass to the BAT (none in your case) as well as the output redirection I passed on.  So the same line you created in your new BAT file (good job trying it that way) could be what the task scheduler invokes.  Depending on the version of Windows you are running the task scheduler has a slightly different look and feel, but the capability is always there.

With regard to the "1 file(s) copied", yes, if you want a bit more info in the captured LOG file you can add ECHO statements to your existing BAT file to print some additional information about the copy. The COPY command on its own doesn't display the file name, so you could do something like:

:PROCESS
for /f %%j in ('echo %~t1') do set d=%%j
if "%d%"=="%t%" (
  copy %1 "%dest%"
  echo Copied: "%1"
)
goto :eof

Open in new window

That being said, as I look at your code, what exactly are you trying to do? :-)  It appears you are just copying all files from one directory to another, and there are much more efficient ways of doing that.  And if you used XCOPY for example, it can display the name of each file copied.  I may be missing something, but why not just do this:

@echo off
setlocal
set source=c:\Users\philip\Desktop\Daily
set dest=c:\Users\philip\Desktop\Weekly
xcopy "%source%\*.*" "%dest%" /D /F

Open in new window

~bp
0
 
Bill PrewCommented:
What do you want to show up in the LOG file?  And how do you currently run this program, is it via task scheduler or some other mechanism?

If you do the following command at a command line what does it display:

ECHO %DATE%

~bp
0
 
ChrisCommented:
i use the following to put a date relative filename in
set y=%date:~-4%
set m=%date:~3,2%
set d=%date:~0,2%
set a=%y%%m%%d%

that was you can use %a%.log as the log file name
0
Cloud Class® Course: Amazon Web Services - Basic

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

 
ReneGeCommented:

@ECHO OFF
SETLOCAL

REM used wmic to be date format independent
FOR /F "skip=1 tokens=1-3 delims= " %%A IN ('WMIC Path Win32_LocalTime Get Day^,Month^,Year') DO (
	IF "%%C" NEQ "" (
		SET dd=%%A
		SET mm=%%B
		SET yy=%%C
	)
)

set t=%yy%%mm%%dd%
set logfile=%t%.log

::Copy Files Made Or Modified Today
set source=c:\Users\philip\Desktop\Daily
set dest=c:\Users\philip\Desktop\Weekly
pushd "%source%"
for /f %%a in ('dir /b /a-d /o-d') do call :PROCESS "%%a"
goto :eof
popd

:PROCESS
for /f %%j in ('echo %~t1') do set d=%%j
if "%d%"=="%t%" (
	copy %1 "%dest%"
	echo [!errorlevel!] %1>>"%logfile%"
)
goto :eof 

pause

Open in new window

0
 
Bill PrewCommented:
Here's how I usually approach this for scheduled BAT jobs.  However you are initialing the bat script, add the following on to the end of the command line:

>"c:\logs\%DATE:~-4%%DATE:~-10,2%%DATE:~-7,2%.log" 2>&1

Open in new window

This will capture ALL output from the BAT script to the log file, named with todays date (assuming your system used mm/dd/yyyy format for dates, if not we can easily adjust for that.

If you want additional info in this log file just add normal ECHO lines into the BAT file.

The think I like about this is I get to see all the output that would have been sent to the screen from all of the commands, so if there are any errors etc they are in the log and not lost.

~bp
0
 
pagoscheAuthor Commented:
Thanks for all the quick responses.  I will be running it as a scheduled task.  I basically want the log to show that it copied the files and a time stamp of when the copy happened.

billprew- I added the line from your most recent post to right under my last line and ran the script, it copied the files like it was before but didn't create a log.

irweazelwallis- where at should I add your suggestion in my batch file?

ReneGe- I gave your code a shot, it just showed a blank cmd prompt for about 2 seconds and disappeared and didn't copy files or create a log file.

I also want to point out that I am new with scripts and batch files so sorry if I ask questions for something obvious.
0
 
ReneGeCommented:
From a command prompt, what do you see when you run this command?
WMIC Path Win32_LocalTime Get Day,Month,Year
0
 
pagoscheAuthor Commented:
ReneGe- I get this:

Day     Month    Year
25       10         2011

billprew- I gave your last line a try again but put in with my last line in the script instead of below it.  It created the log file 20111025 which is exactly what I want but the log was blank.  

Thanks.
0
 
ReneGeCommented:
Here is a new approach

@ECHO OFF

SETLOCAL EnableDelayedExpansion

set source=c:\Users\philip\Desktop\Daily
set dest=c:\Users\philip\Desktop\Weekly

REM used wmic to be date format independent
	FOR /F "skip=1 tokens=1-3 delims= " %%A IN ('WMIC Path Win32_LocalTime Get Day^,Month^,Year') DO (
		IF "%%C" NEQ "" (
			SET dd=%%A
			SET mm=%%B
			SET yy=%%C
		)
	)
	set t=%yy%-%mm%-%dd%
	set logfile=%yy%%mm%%dd%.log

for /f "delims=" %%A in ('dir /s /b /a-d /o-d "%source%\*.*"') do (
	for /f %%B in ("%%~tA") do if "%%B" EQU "%t%" (
		copy "%%~fA" "%dest%"
		echo [!errorlevel!] "%%~fA"
		echo [!errorlevel!] "%%~fA">>"%logfile%"
	)
)

pause
exit

Open in new window

0
 
ReneGeCommented:
I added /s in line 19 for my test. You may want to remove it.
0
 
ReneGeCommented:
And if you want a cleaner output, add the following at the end of line 21
>NUL
0
 
Bill PrewCommented:
==> billprew- I gave your last line a try again but put in with my last line in the script instead of below it.
==> It created the log file 20111025 which is exactly what I want but the log was blank.  

Sorry, I should have been more clear.  That wasn't intended to be added into your BAT file.  Rather it is intended to be added onto the end of the command line you use when you RUN the bat file.

So, if your bat file is called FOO.BAT now, and you currently do this to run it at a command prompt:

FOO

then do this at the command prompt instead:

FOO >>"c:\logs\%DATE:~-4%%DATE:~-10,2%%DATE:~-7,2%.log" 2>&1

let me know if that still doesn't make sense.

~bp
0
 
Paul TomasiCommented:
In the code below, set your logs variable (see line 6) to point to where you want your log files saved.
@echo off
setlocal

set source=c:\Users\philip\Desktop\Daily
set dest=c:\Users\philip\Desktop\Weekly
set logs=

for /f "skip=1 tokens=1-3" %%a in ('WMIC Path Win32_LocalTime Get Day^, Month^, Year') do (
  set datestamp=%%c%%b%%a
)

pushd "%source%"
set t=%date:~4%
for /f %%a in ('dir /b /a-d /o-d') do call :PROCESS "%%a"
popd
goto :eof

:PROCESS
for /f %%j in ('echo %~t1') do set d=%%j
if "%d%"=="%t%" (
  copy %1 "%dest%"
  echo %1>>"%logs%\%datestamp%.log"
)
goto :eof

Open in new window

0
 
pagoscheAuthor Commented:
ReneGe- I copied your code and ran it, taking out the /s.  All it did was show me a command prompt that said press any key to continue.  Not files transferred and no log was created.

billprew- I am kind of confused on your suggestion.  Doesn't that mean I will have to run that manually?  I am going to be scheduling the .bat file to run every Monday for example.  Not sure how I would run it from a command prompt automatically.

paultomasi- Your script worked except for one thing.  It did create a log and put in the log the file that it copied but in the log there wasn't any kind of a time stamp from when the copy ran and it was given no file name.
0
 
Paul TomasiCommented:
What information do you actually want inside the log file and how do you want it to appear....

Please give an example if you are able to.
0
 
pagoscheAuthor Commented:
Basically, I want it to show the date and time that the copy took place and then the file names below it so something like this.

20111026 10:25AM

file.txt
file2.txt
file3.txt
0
 
pagoscheAuthor Commented:
billprew- I put your suggestion in another batch file that I could use in my task scheduler and that worked great.  It created a log file with the file name the way I wanted and ran my copy perfectly.  Only thing I have a question about now is, I didn't notice that when my batch file runs and copy and pastes the file, it would show like this:

1 file(s) copied.
1 file(s) copied.

So that is how my log shows.  I am guessing the only way that I get the log to show the file names of the files that were copied and pasted from the source to the destination is redoing my script?
0
 
ReneGeCommented:
ReneGe- I copied your code and ran it, taking out the /s.  All it did was show me a command prompt that said press any key to continue.  Not files transferred and no log was created.

Works for me.

So maybe adding the pushd and popd will help.

Also added your new requirements

@ECHO OFF

SETLOCAL EnableDelayedExpansion

set source=c:\Users\philip\Desktop\Daily
set dest=c:\Users\philip\Desktop\Weekly
set Flag=0

REM used wmic to be date format independent
FOR /F "skip=1 tokens=1-6" %%A IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Month^,Second^,Year /Format:table') DO (
	IF %%A GTR 0 (
	SET t=%%F-%%D-%%A
	SET LogFile=%~dp0%%F%%D%%A.log
	SET LogDate=%%F-%%D-%%A %%B:%%C
	)
)
ECHO %LogDate%>"%logfile%"
pushd "%source%"
for /f "delims=" %%A in ('dir /b /a-d /o-d *.*') do (
	for /f %%B in ("%%~tA") do if "%%B" EQU "%t%" (
		SET Flag=1
		copy "%%~fA" "%dest%" >NUL
		echo [!errorlevel!] "%%~fA"
		echo [!errorlevel!] "%%~fA">>"%logfile%"
	)
)
popd
IF %Flag% EQU 0 ECHO No files found for today
IF %Flag% EQU 0 ECHO No files found for today>>"%logfile%"
pause
exit

Open in new window

0
 
Paul TomasiCommented:
Please try this revised code.
@echo off
setlocal

set source=c:\Users\philip\Desktop\Daily
set dest=c:\Users\philip\Desktop\Weekly
set logs=

for /f "skip=1 tokens=1-5" %%a in ('WMIC Path Win32_LocalTime Get Day^, Month^, Year^, hour^, minute') do (
  if %%b gtr 12 (
    set /a h=%%b-12
    set ampm=PM
  ) else (
    set /a h=%%b
    set ampm=AM
  )
  set "d=0%%a" & set "m=0%%d" & set "y=0%%e" & set "t=0%%c"
)

set "d=%d:~-2%" & set "m=%m:~-2%" & set "y=%y:~-4%" & set "h=%h:~-2%" & set "t=%t:~-2%"

set datestamp=%y%%m%%d%
set timestamp=%h%:%t%%ampm%

echo %datestamp% %timestamp%>>"%logs%\%datestamp%.log"
echo.>>"%logs%\%datestamp%.log" 

pushd "%source%"
set t=%date:~4%
for /f %%a in ('dir /b /a-d /o-d') do call :PROCESS "%%a"
popd

echo.>>"%logs%\%datestamp%.log"
goto :eof

:PROCESS
for /f %%j in ('echo %~t1') do set d=%%j
if "%d%"=="%t%" (
  copy %1 "%dest%" >nul
  echo %1>>"%logs%\%datestamp%.log"
)
goto :eof

Open in new window

0
 
Paul TomasiCommented:
billprew

i seem to remember somewhere he wants a log file of files copied... he was specific about the entries in the log file (see http:#37031206).

i also seem to remember he only wants files copied if they match a particular date and/or time...

i think for the most part he was up and running - admittedly, it may not be the way we might have chosen to do it however, he requested help in adding code to his existing code which would create a datestamp-named log file (now where have I heard that one before...) and code to log each file copied.

if that helps you any.... :)
0
 
Bill PrewCommented:
Right, but since his original code didn't only copy "today's" files I wanted to understand the goal so that I could help towards the best approach.

xcopy /D will copy newer and updated files, which might be something he wasn't aware of.

Or robocopy /MIR might make sense if he's trying to have a mirrored backup.

Another approach rather than checking for today's dated files would be to copy the ones that don't already exist in the destination.

Hard to know if I can suggest a better approach without asking for a little clarification, so I went for it.

While it wasn't the exact question that was originally asked, I'd hate to see him get the date stamped log file all buttoned up only to find that the script doesn't do what he needs or wants.

~bp
0
 
ReneGeCommented:
Inspired by Paul's ampm; I fixed the 12:00 PM -> 0:00 PM to 12:00 PM

@ECHO OFF

SETLOCAL EnableDelayedExpansion

set source=c:\Users\philip\Desktop\Daily
set dest=c:\Users\philip\Desktop\Weekly
set Flag=0

set source=C:\temp
set dest=%~dp0dest

REM used wmic to be date format independent
FOR /F "skip=1 tokens=1-6" %%A IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Month^,Second^,Year /Format:table') DO (
	IF %%A GTR 0 (
		IF %%B EQU 12 (
			SET h=%%B
			SET ampm=PM
		) ELSE (
			IF %%B GEQ 13 (
				SET /a h=%%B-12
				SET ampm=PM
			) ELSE (
				SET h=%%B
				SET ampm=AM
			)
		)
		SET t=%%F-%%D-%%A
		SET LogFile=%~dp0%%F%%D%%A.log
		SET LogDate=%%F-%%D-%%A !h!:%%C !ampm!
	)
)
ECHO %LogDate%>"%logfile%"
pushd "%source%"
for /f "delims=" %%A in ('dir /b /a-d /o-d *.*') do (
	for /f %%B in ("%%~tA") do if "%%B" EQU "%t%" (
		SET Flag=1
		copy "%%~fA" "%dest%" >NUL
		echo [!errorlevel!] "%%~fA"
		echo [!errorlevel!] "%%~fA">>"%logfile%"
	)
)
popd
IF %Flag% EQU 0 ECHO No files found for today
IF %Flag% EQU 0 ECHO No files found for today>>"%logfile%"
pause
exit

Open in new window

0
 
ReneGeCommented:
Oups, forgot to remove lines 9 and 10. These are for my own tests, so please DELETE or REM them.
0
 
pagoscheAuthor Commented:
Ok, thank you for all the help.  Sorry if I was confusing or unclear of what I want but I think I got what I want now.

billprew- in my batch file I added echo Copied: "%1" in my code under the process section like you suggested and ran the batch file like this from a command prompt that you suggested earlier:

test.bat >>"c:\users\philip\desktop\logs\%DATE:~-4%%DATE:~-10,2%%DATE:~-7,2%.log" 2>&1
exit

And that gave me exactly what I wanted.  It creates a log 20111026 and in the file shows:

        1 file(s) copied.
Copied: "Test.txt"
        1 file(s) copied.
Copied: "Test1.txt"
        1 file(s) copied.
Copied: "Test2.txt"

Thanks to everyone for the help.
0
 
pagoscheAuthor Commented:
Thanks again for all the help!!
0
 
Paul TomasiCommented:
ReneGe

Ah! I see I haven't accounted for 12:00 through 12:59... which is also 'PM'.

Oddly enough (without checking) is 12:00 AM or PM? - My guess is it's PM!

Well spotted!



0
 
ReneGeCommented:
Yes, 12h is as PM, as 0h is AM

Cheers,
Rene
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.