Generate unique file name with timestamp in batch

2019-01-21 22:06发布

问题:

In my .bat file I want to generate a unique name for files/directories based on date-time.

e.g.

Build-2009-10-29-10-59-00

The problem is that %TIME% won't do because it contains characters that are illegal in filename (e.g. :).

Is there something like tr in batch files?

Any other ideas how to solve this (that don't require extra command line utilities aside from the batch interpreter)?

回答1:

EDIT: A better way of doing this is to take a date/time string that has a defined and unchanging format instead of using the locale-defined ones from %date% and %time%. You can use the following to get it:

for /f "skip=1" %%x in ('wmic os get localdatetime') do if not defined mydate set mydate=%%x

It yields something like 20120730203126.530000+120 and you can use that to construct your file names.


(Old answer below)

You can simply replace the offending character with an empty string:

echo %time::=%

The syntax %var:str1=str2% takes the environment variable (or pseudo-variable in case of %TIME% and replaces str1 by str2. If nothing follows after the equals sign then str1 is simply deleted.

In your specific case I think you'd want the following:

rem cut off fractional seconds
set t=%time:~0,8%
rem replace colons with dashes
set t=%t::=-%
set FileName=Build-%date%-%t%

A more brute-force way in case you don't know whether colons are used (but the order of the time would be the same):

set FileName=Build-%date%-%time:~0,2%-%time:~3,2%-%time:~6,2%

All preceding things, however, assume that you use standard ISO 8601 date format, i. e. 2009-10-29. I'd assume this as simply normal, but some people use other formats so be careful. But since you didn't ask about the date I was assuming you didn't have a problem there.



回答2:

Following up on @Joey's and @Kees' answers to make them instantly usable.

On the command line:

FOR /f %a IN ('WMIC OS GET LocalDateTime ^| FIND "."') DO SET DTS=%a
SET DateTime=%DTS:~0,4%-%DTS:~4,2%-%DTS:~6,2%_%DTS:~8,2%-%DTS:~10,2%-%DTS:~12,2%
echo %DateTime%

In a BAT file:

@echo off
REM See http://stackoverflow.com/q/1642677/1143274
FOR /f %%a IN ('WMIC OS GET LocalDateTime ^| FIND "."') DO SET DTS=%%a
SET DateTime=%DTS:~0,4%-%DTS:~4,2%-%DTS:~6,2%_%DTS:~8,2%-%DTS:~10,2%-%DTS:~12,2%
echo %DateTime%

Example output:

2014-10-21_16-28-52


回答3:

I use this to create a unique file name for the execution of the batch file.

REM ****Set up Logging ****
For /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set mydate=%%c-%%a-%%b)
For /f "tokens=1-2 delims=/:" %%a in ("%TIME%") do (set mytime=%%a%%b)
set mytime=%mytime: =0%

set Logname="PCCU_%mydate%_%mytime%.log"
Echo.  >>%Logname% 2>>&1
Echo.=================== >>%Logname% 2>>&1

I had to add the line

set mytime=%mytime: =0%

because I had the same problem where a blank was being entered before 10 AM, now I get 09 instead of 9. I also reuse the %mydate% and %mytime% variable for other files that I create with this script so that they all have the same date time stamp.



回答4:

This routine, actually only one line, works on every system set to any date or time format.
Output of line 1 is in format 20140725095527.710000+120

The actual date/time format you need is determined in line 2. You can format it however you want.
Just add the resulting DateTime variable to your filename ie. Filename_%DateTime%.log

::=======================================================================
::== CREATE UNIQUE DateTime STRING IN FORMAT YYYYMMDD-HHMMSS
::=======================================================================
FOR /f %%a IN ('WMIC OS GET LocalDateTime ^| FIND "."') DO SET DTS=%%a

SET DateTime=%DTS:~0,8%-%DTS:~8,6% | REM OUTPUT = 20140725-095527


回答5:

I made this universal, Will work on any environment where date format may be different.

echo off
if not exist "C:\SWLOG\" mkdir C:\SWLOG
cd C:\SWLOG\
cmd /c "powershell get-date -format ^"{yyyyMMdd-HHmmss}^""> result.txt
REM echo %time% > result.txt
type result.txt > result1.txt
set /p filename=<result1.txt
echo %filename%
del C:\SWLOG\result.txt
del C:\SWLOG\result1.txt


回答6:

To make the code in the previous example work, I needed to adjust slightly. I presume this is because my PC is using a UK date format. To get back "2014-04-19" in mydate I needed:

For /f "tokens=1-3 delims=/ " %%a in ('date /t') do (set mydate=%%c-%%b-%%a)

Below I've pasted my total script, and included an example of how to use the filename

For /f "tokens=1-3 delims=/ " %%a in ('date /t') do (set mydate=%%c-%%b-%%a)
For /f "tokens=1-2 delims=/:" %%a in ("%TIME%") do (set mytime=%%a%%b)
set mytime=%mytime: =0%

set Logname="c:\temp\LogFiles\MyLogFile_%mydate%_%mytime%.log"
Robocopy  \\sourceserver\Music H:\MyBackups\Music /MIR /FFT /Z /XA:H /W:5 /np /fp /dcopy:T /unilog:%Logname% /tee 

Hope this helps!



回答7:

If you can guarantee that the machine has a specific version of Python installed on it and accessible in the system's PATH, you can use this solution:

FOR /F "tokens=* USEBACKQ" %%F IN (`python -c "import datetime; print 
datetime.datetime.now().replace(microsecond=0).isoformat().replace(':', '-')"`) DO (
SET TIMESTAMP=%%F
)
ECHO %TIMESTAMP%

This will put the current local ISO-8601(ish) date representation into a %TIMESTAMP% variable and echo it out, like so:

2017-05-25T14:54:37

I've put replace(':', '-') after the isoformat() so that the resultant string can be used in a filename or directory, since : is a forbidden character in the Windows filesystem.