Membuat nama file sebagai stempel waktu dalam pekerjaan batch


90

Kami memiliki pekerjaan batch yang berjalan setiap hari dan menyalin file ke folder pengambilan. Saya juga ingin mengambil salinan file itu dan memasukkannya ke folder arsip dengan nama file

 yyyy-MM-dd.log

Apa cara termudah untuk melakukan ini dalam pekerjaan batch Windows?

Saya pada dasarnya mencari yang setara dengan perintah Unix ini:

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

Saat mendapatkan String Tanggal dengan format yang Anda inginkan di windows. File bat terlihat seburuk solusi yang diusulkan. Sejujurnya, periksa saja bahasa pemrograman apa yang tersedia di mesin, misalnya java, ruby, perl atau yang lainnya, dan buat 5 detik yang dapat dieksekusi untuk memberikan apa yang Anda inginkan. Saya tidak akan membuang waktu untuk memelihara file .bat yang membutuhkan lebih dari satu baris kode untuk mendapatkan tanggal dengan format yang tepat.
99Sono

Jawaban:


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

Tapi itu tergantung pada lokalnya. Saya tidak yakin apakah %DATE%dilokalkan, atau tergantung pada format yang ditentukan untuk tanggal singkat di Windows.

Berikut adalah cara yang tidak tergantung lokal untuk mengekstrak tanggal saat ini dari jawaban ini , tetapi bergantung pada WMICdan 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
Perlu melakukan sedikit mengutak-atik indeks tetapi ini tampaknya telah berhasil. (meskipun tidak sepenuhnya yakin saya memahami logika minus-indeks)% TANGGAL: ~ -4% -% TANGGAL: ~ -7, -5% -% TANGGAL: ~ -10, -8% .log
Eoin Campbell

1
Jika Anda ingin menggunakan semua indeks positif, Anda dapat menggunakan:% DATE: ~ 10,4% -% DATE: ~ 4,2% -% DATE: ~ 7,2%
opello

(Saya hanya mengambil ini dari hal lain yang saya kerjakan, itu sudah lama sekali, dan saya tidak tahu mengapa saya melakukannya seperti yang saya lakukan awalnya, heh.)
opello

3
Ini merusak lokal lain. Dalam kasus saya, perintah kembali 2014-5.-01(ketika itu akan terjadi 2014-05-26). Jadi berhati-hatilah, jika Anda menerbitkan skrip yang berisi ini!
amenthes

5
Gunakan ini untuk waktu (menghapus milidetik): %time:~-11,2%-%time:~-8,2%-%time:~-5,2%
MRC

48

Ini berfungsi untuk saya dan merupakan solusi yang aman untuk nama file (meskipun ini menghasilkan format 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

Perintah pertama mengambil DATE dan menggantikannya /dengan -, mengambil TIME dan menggantinya :dengan -, dan menggabungkannya ke dalam format DATE @ TIME. setPernyataan kedua menghapus spasi apa pun, dan pernyataan ketiga setmenggantikan ,dengan .dan menambahkan .jpgekstensi.

Kode di atas digunakan dalam skrip kecil yang menarik gambar dari kamera IP keamanan untuk diproses lebih lanjut:

: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

output di konsol saya adalah 10-12-2014@14-22-59,44.jpgdengan koma sebelum milidetik
BeNdErR

1
Coba tambahkan set SAVESTAMP=%SAVESTAMP:,=.%.jpgsebelum echopernyataan. Jika itu berhasil, saya akan memperbarui jawabannya.
Daniel Sokolowski

1
Ini tidak bergantung pada lokal. Mengembalikan 08.06.2016@15-42-20,33.jpgdengan laptop Jerman saya dan dengan laptop Wed06-08-2016@15-43-45.89.jpgInggris saya.
Hannobo

5
Tapi itu masih bukan independen lokal atau membuat format (iso8601) yang benaryyyy-MM-dd
jeb

1
Sangat menjengkelkan bahwa baris pertama masih mengklaim itu independen lokal, hanya untuk melihatnya bukan setelah mencoba ...
m3tikn0b

16

HANYA Untuk Lokal Prancis (Prancis) , hati-hati karena /muncul pada tanggal:

echo %DATE%
08/09/2013

Untuk masalah file log kami, berikut adalah proposal saya untuk HANYA Lokal Prancis :

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%

Luar biasa! Agak sulit untuk dibaca, tetapi memungkinkan untuk memformat keluaran seperti yang Anda inginkan.
davitof

2
Bagus tapi hati-hati jika Anda ingin menghindari karakter putih karena HOUR dapat berupa 1 digit yang dirender seperti itu: "_0:00"(karakter garis bawah adalah spasi)
daVe

1
Saya mendapatkan "log- / 18 /. 0.Sa- 9.16.txt" untuk jawaban ini.
ledlogic

@ledlogic: apa lokal Anda? Jawaban ini untuk bahasa Prancis.
Aubin

1
TIDAK berhasil Saya mendapatkan ini di Windows 7 - log- / 05 /. 0. We-18.13.tx
Sam B

10

Berikut adalah solusi independen lokal (salin ke file bernama 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%

Saya meletakkan semua skrip .cmd saya ke dalam folder yang sama (% SCRIPTROOT%); skrip apa pun yang membutuhkan nilai tanggal / waktu akan memanggil SetDateTimeComponents.cmd seperti pada contoh berikut:

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%

Seperti yang ditunjukkan contoh, Anda dapat memanggil SetDateTimeComponents.cmd kapan pun Anda perlu memperbarui nilai tanggal / waktu. Menyembunyikan skrip parsing waktu dalam file SetDateTimeComponents.cmd miliknya adalah cara yang bagus untuk menyembunyikan detail yang jelek, dan, yang lebih penting, hindari kesalahan ketik.


2
maaf, ini tidak bergantung pada lokal: di Windows Prancis saya, saya mendapatkan "18 -2014- @ 13:14:43"
davitof

1
Dapat mengonfirmasi: tidak independen lokal. prompt $d $tmengembalikan 30.05.2016 15: 35: 56,93 di sistem saya.
Hannobo

7

Karena gagasan untuk merobek %DATE%dan %TIME%memisahkan serta menumbuk kembali tampak rapuh, berikut adalah alternatif yang menggunakan PowerShell 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

Referensi untuk get-dateada di sini , dengan opsi format untuk gaya .NET dan gaya UNIX.


6

Saya sering menggunakan ini, dan memasukkan semuanya ke dalam satu perintah salin. Salinan example.txt berikut sebagai example_YYYYMMDD_HHMMSS.txt dan tentu saja Anda dapat memodifikasinya agar sesuai dengan format pilihan Anda. Tanda kutip hanya diperlukan jika ada spasi di filespec. Jika Anda ingin menggunakan kembali tanggal / stempel waktu yang sama persis, Anda harus menyimpannya dalam variabel.

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

Ini akan memastikan bahwa hasilnya adalah nilai 2-digit ... Anda dapat mengatur ulang keluaran sesuai dengan keinginan Anda dan mengujinya dengan menghapus komentar di bagian diagnostik. Nikmati!

(Saya meminjam banyak ini dari forum lain ...)

:: ------------------ 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

Buat file dengan tanggal sekarang sebagai nama file (mis. 2008-11-08.dat)

echo hello > %date%.dat    

Dengan tanggal saat ini tetapi tanpa "-" (mis. 20081108.dat)

echo hello > %date:-=%.dat   

2

Mungkin ini bisa membantu:

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

atau

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

Bagus sekali Secko ... bahwa nilai% date% sepertinya memiliki apa yang saya cari. Ada kemungkinan Anda bisa menjelaskan pernyataan SET. Apa sebenarnya $ d $ _set & $ t $ h $ h $ h
Eoin Campbell

1
set adalah pernyataan "SET variabel". Dimana variabel tanggal adalah $ d $ _ (hari + sisa) dan variabel waktu adalah $ t $ h $ h $ h (waktu + ms). Saya mencoba untuk menunjukkan bagaimana itu bisa dilakukan dengan satu set variabel itu bisa bekerja dengan baik tanpa baris prompt. Pada dasarnya saya mencoba melakukan set date ini =% YYYY %% MM %% DD% tetapi saya menjalankan Linux di sini dan mengkompilasi skrip di SciTE jadi saya tidak tahu apakah itu berfungsi. Maaf jika tidak berhasil.
Secko

Lupa menambahkan, $ _ adalah baris baru.
Secko

1
Coba juga, @prompt // $ d $ _ $ t $ h $ h $ h $ h $ h $ h //
Secko

Perhatikan bahwa ini juga tidak bergantung pada lokal. Tanggal diformat dengan pengaturan budaya saat ini, dalam kasus saya DD.MM.YYYY (untuk Jerman).
Hannobo

2

Saya mengumpulkan program C kecil untuk mencetak stempel waktu saat ini (aman lokal, tidak ada karakter buruk ...). Kemudian, saya menggunakan perintah FOR untuk menyimpan hasil dalam variabel lingkungan:

:: 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"

Ini tautannya:

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


2

Saya tahu utas ini sudah tua tetapi saya hanya ingin menambahkan ini di sini karena itu membantu saya banyak mencoba mencari tahu ini semua dan bersihnya. Hal yang menyenangkan tentang ini adalah Anda bisa memasukkannya ke dalam loop untuk file batch yang selalu berjalan. Log up-time server atau sesuatu. Itulah yang saya gunakan untuk itu. Saya harap ini membantu seseorang suatu hari nanti.

@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%

Ini berguna bagi saya, meskipun dalam file ".cmd", titik dua dalam variabel "FreshTime" menyebabkan kesalahan saat digunakan untuk nama file di cmdline "robocopy" saya: ERROR : Invalid Parameter #12 : "/LOG:C:\opt\Sync_08.10.2020_16:27:39.log"Sebagai perbaikan, saya menggunakan tanda hubung:set FreshTime=%hour%-%min%-%secs%
netdesignate

2

Anda cukup mendeteksi format lokal saat ini dan bisa mendapatkan tanggal dalam format Anda, misalnya:

::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

Saya tahu ini adalah posting lama, tetapi ada jawaban yang JAUH lebih sederhana (meskipun mungkin hanya berfungsi di versi windows yang lebih baru). Cukup gunakan parameter / t untuk perintah dos DATE dan TIME untuk hanya menampilkan tanggal atau waktu dan tidak meminta Anda untuk mengaturnya, seperti ini:

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

1

1) Anda dapat mengunduh GNU coreutils yang disertakan dengan tanggal GNU

2) Anda dapat menggunakan VBScript , yang membuat manipulasi tanggal lebih mudah di 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

Jalankan skrip sebagai:

c:\test> cscript /nologo myscript.vbs

0

Ini bekerja dengan baik dengan lokal Jerman (saya), harus mungkin untuk menyesuaikannya dengan kebutuhan Anda ...

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%bekerja untuk lokasi Portugis juga! Maksud saya YYYYMMDD
Fernando Fabreti

0

Untuk file zip besar untuk penerapan, saya menggunakan seperempat jam. Tidak ada orang lain di halaman ini yang menyebutkannya sebelumnya, jadi saya akan meletakkan skrip kecil saya di sini:

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"

Ini belum nol pad seperempat jam dari tengah malam hingga jam 5 pagi, tetapi masih membuatnya sehingga Anda dapat memiliki rilis yang dicap beberapa kali sehari dengan sedikit tabrakan.

Semoga membantu.


0

menggunakan saran Martin dengan sedikit perubahan untuk menambahkan cap waktu ke nama file:

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

Untuk 10:17:21 23/10/2019 Hasilnya adalah:

20191023_10-17-21-rsync2.log

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.