Category Archives: Windows BAT

Right on Date/Time

Date/Time Named Files in DOS Batch

Producing date/time named files for output from DOS Batch

Summary

Good for when you want the output from a .BAT command file to be written to a date/time stamped file.

My Problem

Today I wanted to schedule a job to run on a clients machine several times a day for a number of weeks. Each time it ran I wanted an output file to with a name a bit like this :

DIAG-20100604T120000.txt

I find writing output to files which have their date/time of creation embedded in their names to be so useful it’s something I’m willing to muck around a bit to achieve.

The job i was running was all wrapped up in a .BAT file – how difficult could it be to get a .BAT file to produce a formatted date/time ? Well the answer is sufficiently difficult I side-stepped the problem !

Locale Independent

When I started looking for others who’d formatted date/times in .BAT land I found plenty of that made assumptions about the date/time format present on the machine it was running on but I really dislike using code like that – I’ve been bitten by it too many times in the past .

In the end I decided the only (or at least the easiest) thing to do was to allow a .VBS file to do the actual date/time formatting and allow the .BAT to use that.

First take some VBS

I pulled together a script I called iso.vbs.

The key thing with the VBS is the way the formatted date/time gets used in the last line. We’re going to use that output when we write some .BAT.

function addLeadingZeroIfNess(strIn)
 if len(strIn) < 2 then
 strOut = "0" & strIn
 else
 strOut = strIn
 end if

 addLeadingZeroIfNess = strOut

end function
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
OurDate = Now()
Yr = DatePart("yyyy",OurDate)
Mth = addLeadingZeroIfNess(DatePart("m",OurDate))
Dy = addLeadingZeroIfNess(DatePart("d",OurDate))
Hr = addLeadingZeroIfNess(DatePart("h",OurDate))
Mn = addLeadingZeroIfNess(DatePart("n",OurDate))
Sec = addLeadingZeroIfNess(DatePart("s",OurDate))
ISO = Yr & Mth & Dy & "T" & Hr & Mn & Sec
wscript.echo ISO

Now Add a bit of .BAT

Then I wrote a short .BAT file, iso.bat, which invokes the iso.vbs shown above and then invokes the ‘real’ .BAT which is the one I actually wanted to run, diag.bat

@echo off
for /f "delims=" %%a in ('cscript //nologo iso.vbs') do (set ISODateTime=%%a)
call diag.bat > "DIAG-"%ISODateTime%".txt"

iso.bat uses the formatted date/time  (eg “20100604T120000”) produced by iso.vbs above to assign to the variable %ISODateTime%. The variable is then available to form part of the file name used for the diag.bat output.

A Bit of Context

If the machine I was using had either PowerShell or Python installed Iwould have come at this from a different angle but … it didn’t !

Credit Where Credits Due

A posting by Tom Lavedas in the vistax64 forums put me on the right track for passing the values from VBS to BAT land – for which my thanks.

Iterating over directories using .BAT

Wildcard Directory Copy in DOS Batch

Moving lots of directories using DOS Batch and wild cards

Summary

This is great for those hideous clean up jobs where you have masses of sub-directories and you want to move a large subset of them somewhere else.

My Problem

I had a directory and it was full of sub-directories looking like this :


2009-12-01 07:33 111-y-888
2009-12-01 07:32 123-x-456
2009-12-01 07:32 123-y-456
2009-12-01 07:32 125-y-456
2009-12-01 07:33 876-x-342
2009-12-01 07:33 999-x-123
...

There were thousands of these things and I only wanted to remove the ones that had an ‘x’ in the middle.

No problem I thought XCopy will do this. Well strange to say but if you want to use wild cards – and clearly I did – XCopy won’t drill down and copy the contents of the director you’re copying. You can use the /E flag and get an empty directory copied but not the actual contents.

Weirdo DOS Batch arguments !

Weirdo DOS Batch arguments to the rescue ! I wrote a one line .BAT file like this :

for /d %%X in (%1) do move %%X %2\%%~nX

I called that movedirs.bat and then to move all the ‘x’ directories from E:\ABC to E:\XYZ I called it like this

movedirs.bat E:\ABC\*x* E:\XYZ

which uses a for loop to process each directory which matches the wildcard individually and uses xcopy on each sub-directory within the for loop.

The gory details

The /d argument on the ‘for’ ensures that only directories are processed. The ‘~n’ modifier on the %%X variable means that the original sub-directory name (as opposed to the entire path) is used as the target within the second command line argument.

So good I wrote it twice

Just to be up front this post is based on a stackoverflow question I posed and then answered myself. It seemed too useful to just be there so I recycled it for my blog.