Створення імені файлу як позначки часу в пакетному завданні


90

У нас є пакетне завдання, яке виконується щодня та копіює файл у папку для отримання. Я також хочу взяти копію цього файлу та помістити його в папку архіву з назвою файлу

 yyyy-MM-dd.log

Який найпростіший спосіб зробити це в пакетній роботі Windows?

В основному я шукаю еквівалент цієї команди Unix:

cp source.log `date +%F`.log

Отримання рядка дати у потрібному форматі у файлах .bat Windows виглядає так само погано, як запропоновані рішення. Чесно кажучи, просто перевірте, які мови програмування доступні на машині, наприклад, java, ruby, perl чи щось інше, і зробіть 5-секундний виконуваний файл, щоб дати вам те, що ви хочете. Я б не витрачав часу на підтримку файлу .bat, який вимагає більше одного рядка коду для отримання дати у відповідному форматі.
99 Sono

Відповіді:


105
CP source.log %DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%.log

Але це залежить від мови. Я не впевнений, що %DATE%це локалізовано або залежить від формату, вказаного для короткої дати в Windows.

Ось спосіб , що не залежить від локалі, витягти поточну дату з цієї відповіді , але це залежить від WMICта FOR /F:

FOR /F %%A IN ('WMIC OS GET LocalDateTime ^| FINDSTR \.') DO @SET B=%%A
CP source.log %B:~0,4%-%B:~4,2%-%B:~6,2%.log

6
Потрібно трохи возитися з індексами, але, схоже, це зробило трюк. (хоча і не повністю впевнений, що я розумію логіку мінус-індексу)% DATE: ~ -4% -% DATE: ~ -7, -5% -% DATE: ~ -10, -8% .log
Eoin Campbell

1
Якщо ви хочете використовувати всі позитивні індекси, ви можете використати:% DATE: ~ 10,4% -% DATE: ~ 4,2% -% DATE: ~ 7,2%
opello

(Я просто взяв це з чогось іншого, над чим працював, це було дуже давно, і я навіть не уявляю, чому я зробив це так, як це робив спочатку, хе.)
opello

3
Це не справляється з іншими мовами. У моєму випадку команда повертається 2014-5.-01(коли це буде 2014-05-26). Тому будьте дуже обережні, якщо ви публікуєте сценарії, що містять це!
amenthes

5
Використовуйте це для часу (видаляє мілісекунди): %time:~-11,2%-%time:~-8,2%-%time:~-5,2%
MRC

48

Це спрацювало для мене і було безпечним рішенням для імен файлів (хоча генерує формат MM-dd-YYYY):

C:\ set SAVESTAMP=%DATE:/=-%@%TIME::=-%
C:\ set SAVESTAMP=%SAVESTAMP: =%
C:\ set SAVESTAMP=%SAVESTAMP:,=.%.jpg
C:\ echo %SAVESTAMP%
11-04-2012@20-52-42.79.jpg

Перша команда приймає DATE і замінює /на -, бере TIME і замінює :на -, і об'єднує їх у формат DATE @ TIME. Другий setоператор видаляє пробіли, а третій setЗамінює ,з .і додає .jpgрозширення.

Наведений вище код використовується в невеликому скрипті, який витягує зображення з IP-камери безпеки для подальшої обробки:

:while
set SAVESTAMP=%DATE:/=-%@%TIME::=-%
set SAVESTAMP=%SAVESTAMP: =%
set SAVESTAMP=%SAVESTAMP:,=.%.jpg
wget-1.10.2.exe --tries=0 -O %SAVESTAMP% http://admin:<password>@<ip address>:<port>/snapshot.cgi
timeout 1
GOTO while

на моїй консолі виводиться 10-12-2014@14-22-59,44.jpgкома перед мілісекундами
BeNdErR

1
Спробуйте додати set SAVESTAMP=%SAVESTAMP:,=.%.jpgперед echoтвердженням. Якщо це спрацює, я оновлю відповідь.
Даніель Соколовський

1
Це не залежить від локалі. Повертається 08.06.2016@15-42-20,33.jpgна моєму німецькому ноутбуці та Wed06-08-2016@15-43-45.89.jpgна моєму англійському.
Hannobo

5
Але це все ще ні локальна незалежність, ні це створює правильний (iso8601) форматyyyy-MM-dd
'16

1
Прикро, що перший рядок все ще стверджує, що він не був незалежним від мови, просто щоб побачити, що це не після випробування ...
m3tikn0b

16

Тільки для французької локалі (Франція) , будьте обережні, оскільки вона /з’являється в даті:

echo %DATE%
08/09/2013

Для нашої проблеми журналу, ось моя пропозиція Тільки для французької мови :

SETLOCAL
set LOGFILE_DATE=%DATE:~6,4%.%DATE:~3,2%.%DATE:~0,2%
set LOGFILE_TIME=%TIME:~0,2%.%TIME:~3,2%
set LOGFILE=log-%LOGFILE_DATE%-%LOGFILE_TIME%.txt
rem log-2014.05.19-22.18.txt
command > %LOGFILE%

Відмінно! Трохи важко читати, але це дозволяє форматувати вихід, як ви хочете.
давітоф

2
Чудово, але будьте обережні, якщо хочете уникати білих символів, оскільки ГОДИНА може бути однозначною, переданою таким чином: "_0:00"(підкреслений символ - пробіл)
daVe

1
Я отримую "log- / 18 /. 0.Sa- 9.16.txt" для цієї відповіді.
ledlogic

@ledlogic: яка ваша мова? Ця відповідь стосується французької мови.
Обен

1
НЕ працює Я отримую це в Windows 7 - log- / 05 /. 0.We-18.13.tx
Sam B

10

Ось рішення, незалежне від локалі (скопіюйте у файл із назвою SetDateTimeComponents.cmd):

@echo off
REM This script taken from the following URL:
REM http://www.winnetmag.com/windowsscripting/article/articleid/9177/windowsscripting_9177.html

REM Create the date and time elements.
for /f "tokens=1-7 delims=:/-, " %%i in ('echo exit^|cmd /q /k"prompt $d $t"') do (
   for /f "tokens=2-4 delims=/-,() skip=1" %%a in ('echo.^|date') do (
      set dow=%%i
      set %%a=%%j
      set %%b=%%k
      set %%c=%%l
      set hh=%%m
      set min=%%n
      set ss=%%o
   )
)

REM Let's see the result.
echo %dow% %yy%-%mm%-%dd% @ %hh%:%min%:%ss%

Я помістив усі свої скрипти .cmd в одну папку (% SCRIPTROOT%); будь-який скрипт, якому потрібні значення дати / часу, буде викликати SetDateTimeComponents.cmd, як у наступному прикладі:

setlocal

@echo Initializing...
set SCRIPTROOT=%~dp0
set ERRLOG=C:\Oopsies.err

:: Log start time
call "%SCRIPTROOT%\SetDateTimeComponents.cmd" >nul
@echo === %dow% %yy%-%mm%-%dd% @ %hh%:%min%:%ss% : Start === >> %ERRLOG%

:: Perform some long running action and log errors to ERRLOG.

:: Log end time
call "%SCRIPTROOT%\SetDateTimeComponents.cmd" >nul
@echo === %dow% %yy%-%mm%-%dd% @ %hh%:%min%:%ss% : End === >> %ERRLOG%

Як показано в прикладі, ви можете викликати SetDateTimeComponents.cmd щоразу, коли вам потрібно оновити значення дати / часу. Приховування сценарію синтаксичного аналізу часу у власному файлі SetDateTimeComponents.cmd - це приємний спосіб приховати негарні деталі та, що ще важливіше, уникнути помилок.


2
вибачте, це не залежить від мови: на моєму французькому Windows я отримую "18 -2014- @ 13:14:43"
davitof

1
Може підтвердити: не залежить від мови. prompt $d $tповертається 30.05.2016 15: 35: 56,93 в моїй системі.
Hannobo

7

Оскільки ідея розірвати %DATE%та %TIME%розім’яти та знову затерти їх разом здається в кращому випадку крихкою, ось альтернатива, яка використовує powerhell oneliner:

for /f %i in ('powershell -c "get-date -format yyyy-MM-dd--HH-mm-ss"') do @set DATETIME=%i
set LOGFILE=my-script-%DATETIME%.txt

Посилання на get-dateце тут , з параметрами форматування , як для .NET-стилю і UNIX-стилі.


6

Я часто цим користуюся і розміщую все в одній команді копіювання. Наступні копії example.txt як example_YYYYMMDD_HHMMSS.txt і, звичайно, ви можете змінити його відповідно до вашого бажаного формату. Лапки потрібні лише у тому випадку, якщо у файлі є пробіли. Якщо ви хочете повторно використати точно ту саму дату / мітку часу, вам потрібно буде зберегти її у змінній.

copy "{path}\example.txt" "{path}\_%date:~10,4%%date:~4,2%%date:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.txt"

6

Це гарантуватиме, що на виході буде двозначне значення ... Ви можете переставити вихід на свій смак і протестувати, скасувавши коментарі до розділу діагностики. Насолоджуйтесь!

(Я багато чого запозичив на інших форумах ...)

:: ------------------ Date and Time Modifier ------------------------

@echo off
setlocal

:: THIS CODE WILL DISPLAY A 2-DIGIT TIMESTAMP FOR USE IN APPENDING FILENAMES

:: CREATE VARIABLE %TIMESTAMP%

for /f "tokens=1-8 delims=.:/-, " %%i in ('echo exit^|cmd /q /k"prompt $D $T"') do (
   for /f "tokens=2-4 skip=1 delims=/-,()" %%a in ('echo.^|date') do (
set dow=%%i
set %%a=%%j
set %%b=%%k
set %%c=%%l
set hh=%%m
set min=%%n
set sec=%%o
set hsec=%%p
)
)

:: ensure that hour is always 2 digits

if %hh%==0 set hh=00
if %hh%==1 set hh=01
if %hh%==2 set hh=02
if %hh%==3 set hh=03
if %hh%==4 set hh=04
if %hh%==5 set hh=05
if %hh%==6 set hh=06
if %hh%==7 set hh=07
if %hh%==8 set hh=08
if %hh%==9 set hh=09


:: --------- TIME STAMP DIAGNOSTICS -------------------------

:: Un-comment these lines to test output

:: echo dayOfWeek = %dow%
:: echo year = %yy%
:: echo month = %mm%
:: echo day = %dd%
:: echo hour = %hh%
:: echo minute = %min%
:: echo second = %sec%
:: echo hundredthsSecond = %hsec%
:: echo.
:: echo Hello! 
:: echo Today is %dow%, %mm%/%dd%. 
:: echo.
:: echo. 
:: echo.
:: echo.
:: pause

:: --------- END TIME STAMP DIAGNOSTICS ----------------------

:: assign timeStamp:
:: Add the date and time parameters as necessary - " yy-mm-dd-dow-min-sec-hsec "

endlocal & set timeStamp=%yy%%mm%%dd%_%hh%-%min%-%sec%
echo %timeStamp%

2

Створіть файл із поточною датою як ім'я файлу (напр., 2008-11-08.dat)

echo hello > %date%.dat    

З поточною датою, але без "-" (напр., 20081108.dat)

echo hello > %date:-=%.dat   

2

Можливо, це може допомогти:

echo off
@prompt set date=$d$_ set time=$t$h$h$h
echo some log >> %date% %time%.log
exit

або

echo off
set v=%date%.log
echo some log >> %v%

Приємний один Secko ... що% date% value, здається, має те, що я шукаю. Будь-який шанс ви можете пояснити твердження SET. Що саме $ d $ _set & $ t $ h $ h $ h
Еойн Кемпбелл

1
set - це оператор "змінної SET". Де змінна дати - $ d $ _ (день + решта), а змінна часу - $ t $ h $ h $ h (час + мс). Я намагався показати, як це можна зробити з набором змінних, він може нормально працювати без рядка підказки. Я в основному намагався зробити цю встановлену дату =% YYYY %% MM %% DD%, але я працюю тут під Linux і складаю скрипт на SciTE, тому я не знаю, чи це працює. Вибачте, якщо це не працює.
Secko

Забув додати, $ _ - це новий рядок.
Secko

1
Також спробуйте, @prompt // $ d $ _ $ t $ h $ h $ h $ h $ h $ h //
Secko

Зауважте, що це також не залежить від локалі. Дата відформатована відповідно до поточного налаштування культури, в моєму випадку DD.MM.YYYY (для німецької).
Hannobo

2

Я склав невелику програму на Сі, щоб роздрукувати поточну мітку часу (безпечно для локалі, немає поганих символів ...). Потім я використовую команду FOR, щоб зберегти результат у змінній середовища:

:: Get the timestamp
for /f %%x in ('@timestamp') do set TIMESTAMP=%%x

:: Use it to generate a filename
for /r %%x in (.\processed\*) do move "%%~x" ".\archived\%%~nx-%TIMESTAMP%%%~xx"

Ось посилання:

https://github.com/HarryPehkonen/dos-timestamp


2

Я знаю, що ця тема стара, але я просто хочу додати її сюди, тому що це мені дуже допомогло, намагаючись зрозуміти все це і чисто. Приємно в цьому те, що ви можете помістити його в цикл для командного файлу, який завжди працює. Журнал роботи сервера або щось інше. Це те, для чого я його використовую в будь-якому випадку. Сподіваюся, це колись допоможе комусь.

@setlocal enableextensions enabledelayedexpansion
@echo off

call :timestamp freshtime freshdate
echo %freshdate% - %freshtime% - Some data >> "%freshdate - Somelog.log"

:timestamp
set hour=%time:~0,2%
if "%hour:~0,1%" == " " set hour=0%hour:~1,1%
set min=%time:~3,2%
if "%min:~0,1%" == " " set min=0%min:~1,1%
set secs=%time:~6,2%
if "%secs:~0,1%" == " " set secs=0%secs:~1,1%
set FreshTime=%hour%:%min%:%secs%

set year=%date:~-4%
set month=%date:~4,2%
if "%month:~0,1%" == " " set month=0%month:~1,1%
set day=%date:~7,2%
if "%day:~0,1%" == " " set day=0%day:~1,1%
set FreshDate=%month%.%day%.%year%

Це було корисно для мене, хоча у файлі ".cmd" двокрапки у змінній "FreshTime" спричиняли помилки при використанні для імені файлу в моєму cmdline "robocopy": ERROR : Invalid Parameter #12 : "/LOG:C:\opt\Sync_08.10.2020_16:27:39.log"Як виправлення я використовував тире замість цього:set FreshTime=%hour%-%min%-%secs%
netdesignate

2

Ви можете просто виявити поточний локальний формат і отримати дату у своєму форматі, наприклад:

::for 30.10.2016 dd.MM.yyyy
if %date:~2,1%==. set d=%date:~-4%%date:~3,2%%date:~,2%
::for 10/30/2016 MM/dd/yyyy
if %date:~2,1%==/ set d=%date:~-4%%date:~,2%%date:~3,2%
::for 2016-10-30 yyyy-MM-dd
if %date:~4,1%==- set d=%date:~,4%%date:~5,2%%date:~-2%
::variable %d% have now value: 2016103 (yyyyMMdd)
set t=%time::=%
set t=%t:,=%
::variable %t% have now time without delimiters
cp source.log %d%_%t%.log

2

Я знаю, що це стара публікація, але є набагато простіша відповідь (хоча, можливо, вона працює лише в нових версіях Windows). Просто використовуйте параметр / t для команд dos DATE і TIME, щоб показати лише дату або час, а не пропонувати вам встановити їх, наприклад:

@echo off
echo Starting test batch file > testlog.txt
date /t >> testlog.txt
time /t >> testlog.txt

1

1) Ви можете завантажити GNU coreutils, який поставляється з датою GNU

2) ви можете використовувати VBScript , що полегшує маніпулювання датами в Windows:

Set objFS = CreateObject("Scripting.FileSystemObject")
strFolder = "c:\test"
Set objFolder = objFS.GetFolder(strFolder)
current = Now
mth = Month(current)
d = Day(current)
yr = Year(current)
If Len(mth) <2 Then
    mth="0"&mth
End If
If Len(d) < 2 Then
    d = "0"&d
End If
timestamp=yr & "-" & mth &"-"& d
For Each strFile In objFolder.Files
    strFileName = strFile.Name
    If InStr(strFileName,"file_name_here") > 0 Then
        BaseName = objFS.GetBaseName(strFileName)
        Extension = objFS.GetExtensionName(strFileName)
        NewName = BaseName & "-" & timestamp & "." & Extension
        strFile.Name = NewName
    End If
Next

Запустіть сценарій як:

c:\test> cscript /nologo myscript.vbs

0

Це добре працює з (моєю) німецькою мовою, має бути можливість пристосувати її до ваших потреб ...

forfiles /p *PATH* /m *filepattern* /c "cmd /c ren @file 
%DATE:~6,4%%DATE:~3,2%%DATE:~0,2%_@file"

%DATE:~6,4%%DATE:~3,2%%DATE:~0,2%працює і для португальської локації! Я маю на увазі РРРРММДД
Фернандо Фабреті,

0

Для великих ZIP-файлів для розгортання я використовую чверть годин. Ніхто ще на цій сторінці не згадував про це раніше, тому я розміщу тут свій маленький сценарій:

set /a "quarter_hours=%time:~0,2%*4 + %time:~3,2% / 15"
set "zip_file=release_%DATE:~-4%.%DATE:~4,2%.%DATE:~7,2%.%quarter_hours%.zip"

Ще не обнуляється чверть годин з півночі до п’ятої ранку, але він все ще робить це, щоб ви могли мати штамп-реліз кілька разів на день з кількома зіткненнями.

Сподіваюся, це допомагає.


0

використав пропозицію Мартіна з невеликим налаштуванням, щоб додати позначку часу до імені файлу:

forfiles /p [foldername] /m rsync2.log /c "cmd /c ren @file %DATE:~6,4%%DATE:~3,2%%DATE:~0,2%_%time:~-11,2%-%time:~-8,2%-%time:~-5,2%-@file

Для 10:17:21 23.10.2019 Результат:

20191023_10-17-21-rsync2.log

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.