2009-06-30 100 views
63

Abbiamo un processo batch che viene eseguito ogni giorno e copia un file in una cartella di prelievo. Voglio prendere anche una copia di quel file e rilasciarlo in una cartella di archivio con il nome del fileCreazione di un nome file come data e ora in un processo batch

yyyy-MM-dd.log 

Qual è il modo più semplice per farlo in un processo batch di Windows?

praticamente sto cercando un equivalente di questo comando Unix:

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

Quando si recupera una stringa di data con il formato desiderato nei file windows .bat, le soluzioni proposte sono pessime. Abbastanza onestamente, basta controllare quali linguaggi di programmazione sono disponibili sulla macchina, ad es. java, ruby, perl o qualcos'altro, e fai un eseguibile di 5 secondi per darti quello che vuoi. Non perderei tempo a mantenere il file .bat che richiede più di una riga di codice per ottenere una data con un formato corretto. – 99Sono

risposta

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

Ma è locale dipendente. Non sono sicuro se %DATE% è localizzato o dipende dal formato specificato per la data breve in Windows.

Ecco un modo locale indipendente per estrarre la data corrente da this answer, ma dipende da WMIC e 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 
+3

Si consiglia di inviare un comando SETLOCAL prima di questo. –

+5

Necessario fare un po 'di giocherellare con gli indici ma questo sembra aver fatto il trucco. (anche se non sono sicuro di aver compreso la logica dell'indice negativo) % DATA: ~ -4% -% DATA: ~ -7, -5% -% DATA: ~ -10, -8% .log –

+1

Se si desidera per utilizzare tutti gli indici positivi, è possibile utilizzare: % DATA: ~ 10,4% -% DATA: ~ 4,2% -% DATA: ~ 7,2% – opello

2

Forse questo può aiutare:

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

o

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

Bello uno Secko ... che% date% value sembra avere quello che sto cercando. Qualche possibilità che tu possa spiegare la dichiarazione SET. Cosa sono esattamente $ d $ _set e $ t $ h $ h $ h –

+1

set è una dichiarazione "SET variable". Dove la variabile data è $ d $ _ (giorno + resto) e la variabile temporale è $ t $ h $ h $ h (tempo + ms). Ho provato a mostrare come può essere fatto con un insieme di variabili che può funzionare senza la riga di prompt. Ho provato fondamentalmente a fare questo set date =% YYYY %% MM %% DD% ma sto usando Linux qui e sto compilando lo script su SciTE quindi non so se funziona. Scusa se non funziona. – Secko

+0

Hai dimenticato di aggiungere $ _ è newline. – Secko

2

Creare un file con la data corrente come il nome del file (es 2008-11-. 08.dat)

echo hello > %date%.dat  

con la data corrente, ma senza il "-". (ex 20081108.dat)

echo hello > %date:-=%.dat 
10

Ecco una soluzione indipendente locale (copiare un file denominato 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% 

ho messo tutti i miei script cmd nella stessa cartella (% SCRIPTROOT%); qualsiasi script che ha bisogno di valori di data/ora chiamerà SetDateTimeComponents.cmd come nel seguente esempio:

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% 

Come mostra l'esempio, è possibile chiamare SetDateTimeComponents.cmd ogni volta che è necessario aggiornare i valori di data/ora. Nascondere lo script di analisi del tempo nel proprio file SetDateTimeComponents.cmd è un buon modo per nascondere i brutti dettagli e, soprattutto, evitare errori di battitura.

+1

scusa, questo non è locale- Indipendente: sul mio Windows francese, ricevo "18 -2014- @ 13:14:43" – davitof

+0

Conferma: non indipendente dalla locale. 'prompt $ d $ t' restituisce 30.05.2016 15: 35: 56,93 sul mio sistema. – Hannobo

0

1) È possibile scaricare GNU coreutils che viene fornito con la data GNU

2) è possibile utilizzare VBScript, il che rende manipolazione data più facile in 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 

eseguire lo script come:

c:\test> cscript /nologo myscript.vbs 
5

Ciò garantisce che l'output sia un valore a 2 cifre ... è possibile riorganizzare l'output a proprio piacimento e test annullando la visualizzazione della sezione diagnostica. Godere!

(Ne ho preso in prestito molto da altri forum ...)

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

Questo ha funzionato per me ed era un nome di file soluzione sicura:

C:\ set SAVESTAMP=%DATE:/=-%@%TIME::=-% 
C:\ set SAVESTAMP=%SAVESTAMP: =% 
C:\ set SAVESTAMP=%SAVESTAMP:,=.%.jpg 
C:\ echo %SAVESTAMP% 
[email protected] 

Il primo comando prende una data e sostituisce / con -, prende il tempo e sostituisce : con - e li combina in al formato DATE @ TIME. La seconda istruzione set rimuove gli spazi e aggiunge l'estensione .jpg.

Il codice di cui sopra viene utilizzato in un piccolo script che tira le immagini da una telecamera IP di sicurezza per l'ulteriore elaborazione:

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

l'output sulla mia console è '10-12-2014 @ 14-22-59,44.jpg' con una virgola prima dei millisecondi – BeNdErR

+1

Prova ad aggiungere' set SAVESTAMP =% SAVESTAMP:, =.%. Jpg' prima del ' echo' statement. Se funziona, aggiornerò la risposta. –

+1

Questo non è indipendente dalla locale. Restituisce '08.06.2016 @ 15-42-20,33.jpg' sul mio laptop tedesco e' Wed06-08-2016 @ 15-43-45.89.jpg' su quello inglese. – Hannobo

13

Per Locale Francese (Francia) SOLO, fate attenzione perché / appare la data :

echo %DATE% 
08/09/2013 

per il nostro problema di file di log, ecco la mia proposta di Locale francese è il solo:

012.351.
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% 
+0

Eccellente! Un po 'difficile da leggere, ma consente di formattare l'output esattamente come si desidera. – davitof

+2

Grande, ma fai attenzione se vuoi evitare caratteri bianchi perché HOUR può essere reso in 1 cifra in questo modo: '" _0: 00 "' (il carattere di sottolineatura è uno spazio) – daVe

+1

Ottengo "log-/18 /. 0.Sa - 9.16.txt "per questa risposta. – ledlogic

1

Ho messo insieme un piccolo programma C per stampare il timestamp corrente (locale sicuro, nessun carattere errato ...). Poi, io uso il comando FOR per salvare il risultato in una variabile d'ambiente:

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

Ecco un link:

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

0

So che questo thread è vecchio ma voglio solo aggiungere questo qui perché mi ha aiutato molto a cercare di capire tutto questo ed è pulito. La cosa bella di questo è che potresti metterlo in un ciclo per un file batch che è sempre in esecuzione. Registro di uptime del server o qualcosa del genere. Questo è quello che lo uso comunque. Spero che questo aiuti qualcuno un giorno.

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

Uso frequentemente questo e metto tutto in un comando di copia singola. Le seguenti copie example.txt come esempio_YYYYMMDD_HHMMSS.txt e ovviamente puoi modificarlo per adattarlo al tuo formato preferito. Le virgolette sono necessarie solo se ci sono spazi nel filespec. Se si desidera riutilizzare la stessa data/ora esatta, è necessario memorizzarla in una variabile.

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

Si può semplicemente rilevare il formato locale attuale e possibile ottenere la data nel formato, ad esempio:

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

So che questo è un vecchio post, ma c'è una risposta molto più semplice (anche se forse funziona solo nelle versioni più recenti di Windows). Basta utilizzare il parametro/t per la data e ora i comandi DOS per mostrare solo la data o l'ora e non richiedono di impostare che, in questo modo:

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

Questo metodo funziona bene con la (mia) locale tedesco, dovrebbe essere possibile adattarlo alle tue esigenze ...

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

Perché l'idea di strappare %DATE% e %TIME% a parte e schiacciare di nuovo insieme sembra fragile nella migliore delle ipotesi, ecco un'alternativa che utilizza un oneliner PowerShell:

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 

di riferimento per get-date è here, con il formato opzioni sia per lo stile .NET che per lo stile UNIX.

Problemi correlati