Creating unique filenames in a batch file

Someone today was asking how to create unique filenames. They had some process which ran in a loop, and they wanted to direct the output of that process to a file, but rather than always overwriting the same file, they wanted to keep history using distinctive filenames.

There are a few ways to do this:

Naïve way:

    set FILENAME=basename-%RANDOM%

Later, sort by using dir /od basename*

The problem is that these files have the possibility of being non-unique, since %RANDOM% only generates numbers between 0 and 32767. For a small number of files, you probably won’t get a collision, though, and this is less code than the “better” way below…

Better way:

    for /f “delims=:. tokens=1-4” %%t in (“%TIME: =0%”) do (
        set FILENAME=basename-%%t%%u%%v%%w

This gives you precision down to .01 seconds, which may be overkill, depending on how tight your loop is. It does have one bug as far as sorting goes (unless you use dir /od again, but that’s cheating…); if you run this over midnight, your sorting will be off (00:00:01 will sort before 23:59:59). If you don’t plan on running it overnight, then this should work fine. But for a truly robust system, use…

Best way:

    for /f “delims=/ tokens=1-3” %%a in (“%DATE:~4%”) do (
        for /f “delims=:. tokens=1-4” %%m in (“%TIME: =0%”) do (
            set FILENAME=basename-%%c-%%b-%%a-%%m%%n%%o%%p

This gives you the same precision (.01 seconds) as the previous way, but sorts nicely since the date (YYYY-MM-DD) comes first in the filename.

Caveat to all of these methods: These scripts are not locale-agnostic. If you change your date/time formats, these may need to be tweaked.

Edit: Fixed the reference to %TIME% so that the script works in the morning too.  Time in Windows includes a leading space for single-digit hours.  While spaces aren’t technically a problem – they’re perfectly legal in filenames – they’re sort of a pain…


Edit #2: Several people correctly pointed out that removing the leading space also messes up the sorting.  The scripts now use a leading zero.  Thanks, all!

Comments (0)