Tworzenie nazwy pliku jako sygnatury czasowej w zadaniu wsadowym


90

Mamy zadanie wsadowe, które jest uruchamiane codziennie i kopiuje plik do folderu odbioru. Chcę też zrobić kopię tego pliku i wrzucić ją do folderu archiwum z nazwą pliku

 yyyy-MM-dd.log

Jaki jest najłatwiejszy sposób wykonania tego zadania wsadowego systemu Windows?

Zasadniczo szukam odpowiednika tego polecenia Unix:

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

Uzyskanie ciągu daty w żądanym formacie w plikach .bat systemu Windows wygląda tak źle, jak proponowane rozwiązania. Całkiem szczerze, po prostu sprawdź, jakie języki programowania są dostępne na komputerze, np. Java, ruby, perl lub coś innego i stwórz 5-sekundowy plik wykonywalny, aby dać ci to, czego chcesz. Nie traciłbym czasu na utrzymywanie pliku .bat, który wymaga więcej niż jednej linii kodu, aby uzyskać datę w odpowiednim formacie.
99 Sono

Odpowiedzi:


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

Ale to zależy od lokalizacji. Nie jestem pewien, czy %DATE%jest zlokalizowany, czy też zależy od formatu określonego dla krótkiej daty w systemie Windows.

Oto niezależny od lokalizacji sposób wyodrębnienia bieżącej daty z tej odpowiedzi , ale zależy to od WMICi 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
Trzeba było trochę majstrować przy indeksach, ale wydaje się, że to załatwiło sprawę. (choć nie jestem do końca pewien, czy rozumiem logikę indeksu minus)% DATE: ~ -4% -% DATE: ~ -7, -5% -% DATE: ~ -10, -8% .log
Eoin Campbell

1
Jeśli chcesz użyć wszystkich dodatnich indeksów, możesz użyć:% DATE: ~ 10,4% -% DATE: ~ 4,2% -% DATE: ~ 7,2%
opello

(Wziąłem to z czegoś innego, nad czym pracowałem, to było dawno temu i nie mam pojęcia, dlaczego zrobiłem to tak, jak pierwotnie, heh.)
opello

3
To działa w innych lokalizacjach. W moim przypadku polecenie zwraca 2014-5.-01(kiedy by to było 2014-05-26). Więc bądź bardzo ostrożny, jeśli publikujesz skrypty zawierające to!
amenthes

5
Użyj tego czasu (usuwa milisekundy): %time:~-11,2%-%time:~-8,2%-%time:~-5,2%
MRC

48

To zadziałało dla mnie i było rozwiązaniem bezpiecznym dla nazwy pliku (chociaż generuje format MM-dd-RRRR):

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

Pierwsze polecenie wykonuje się na randkę i zastępuje /się -, ma czas i zastępuje :się -i łączy je w DATE @ format czasu. Druga setinstrukcja usuwa żadnych spacji, a trzeci setzostaje zastąpiony przez ,z .i dołącza .jpgrozszerzenie.

Powyższy kod jest używany w małym skrypcie, który pobiera obrazy z kamery IP bezpieczeństwa do dalszego przetwarzania:

: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

wynik na mojej konsoli ma 10-12-2014@14-22-59,44.jpgprzecinek przed milisekundami
BeNdErR

1
Spróbuj dodać set SAVESTAMP=%SAVESTAMP:,=.%.jpgprzed echostwierdzeniem. Jeśli to zadziała, zaktualizuję odpowiedź.
Daniel Sokolowski

1
To nie jest niezależne od lokalizacji. Zwroty 08.06.2016@15-42-20,33.jpgna moim niemieckim laptopie i Wed06-08-2016@15-43-45.89.jpgna moim angielskim.
Hannobo

5
Ale nadal nie jest niezależny od ustawień regionalnych ani nie tworzy poprawnego (iso8601) formatuyyyy-MM-dd
jeb.

1
To denerwujące, że pierwsza linia nadal twierdzi, że była niezależna od lokalizacji, tylko po to, aby zobaczyć, że nie jest po wypróbowaniu ...
m3tikn0b

16

TYLKO dla French Locale (France) , bądź ostrożny, ponieważ /pojawia się w dacie:

echo %DATE%
08/09/2013

W przypadku naszego problemu z plikiem dziennika, oto moja propozycja TYLKO dla języka francuskiego :

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%

Świetny! Trochę trudne do odczytania, ale pozwala sformatować dane wyjściowe tak, jak chcesz.
davitof

2
Świetnie, ale bądź ostrożny, jeśli chcesz uniknąć białych znaków, ponieważ GODZINA może być 1 cyfrą renderowaną w ten sposób: "_0:00"(podkreślony znak jest spacją)
daVe

1
Otrzymuję „log- / 18 /. 0.Sa- 9.16.txt” dla tej odpowiedzi.
ledlogic

@ledlogic: jakie są twoje ustawienia regionalne? Ta odpowiedź dotyczy francuskiego języka.
Aubin

1
NIE działa, dostaję to na Windows 7 - log- / 05 /. 0.We-18.13.tx
Sam B

10

Oto rozwiązanie niezależne od ustawień regionalnych (skopiuj do pliku o nazwie 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%

Umieściłem wszystkie moje skrypty .cmd w tym samym folderze (% SCRIPTROOT%); każdy skrypt, który potrzebuje wartości daty / godziny, wywoła SetDateTimeComponents.cmd, jak w poniższym przykładzie:

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%

Jak pokazuje przykład, możesz wywołać SetDateTimeComponents.cmd zawsze, gdy musisz zaktualizować wartości daty / godziny. Ukrywanie skryptu analizującego czas w jego własnym pliku SetDateTimeComponents.cmd to dobry sposób na ukrycie brzydkich szczegółów i, co ważniejsze, uniknięcie literówek.


2
przepraszam, to nie jest niezależne od lokalizacji: w moim francuskim systemie Windows otrzymuję komunikat „18 -2014- @ 13:14:43”
davitof

1
Potwierdza: brak niezależności od lokalizacji. prompt $d $tzwraca 30.05.2016 15: 35: 56,93 w moim systemie.
Hannobo

7

Ponieważ idea rozdarcia %DATE%i %TIME%od siebie i zacierania je z powrotem razem wydaje się kruchy w najlepszym razie, oto alternatywa, która używa 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

Odniesienie do get-dateznajduje się tutaj , z opcjami formatowania zarówno w stylu .NET, jak i w stylu UNIX.


6

Często tego używam i umieszczam wszystko w jednym poleceniu kopiowania. Poniższe kopiuje przykład.txt jako przykład_RRRRMMDD_HHMMSS.txt i oczywiście możesz go zmodyfikować, aby dopasować go do preferowanego formatu. Cudzysłowy są konieczne tylko wtedy, gdy w specyfikacji pliku są spacje. Jeśli chcesz ponownie użyć dokładnie tej samej daty / sygnatury czasowej, musisz zapisać je w zmiennej.

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

Zapewni to, że dane wyjściowe będą miały wartość 2-cyfrową ... możesz zmienić ustawienie wyjścia zgodnie z własnymi upodobaniami i przetestować, usuwając komentarz z sekcji diagnostycznej. Cieszyć się!

(Wiele z tego pożyczyłem z innych forów ...)

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

Utwórz plik z bieżącą datą jako nazwą pliku (np. 2008-11-08.dat)

echo hello > %date%.dat    

Z aktualną datą, ale bez „-” (np. 20081108.dat)

echo hello > %date:-=%.dat   

2

Może to pomoże:

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

lub

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

Niezłe Secko ... ta% date% value wydaje się mieć to, czego szukam. Masz szansę wyjaśnić instrukcję SET. Czym dokładnie są $ d $ _set i $ t $ h $ h $ h
Eoin Campbell

1
set to instrukcja „SET zmienna”. Gdzie zmienną daty jest $ d $ _ (dzień + reszta), a zmienną czasu jest $ t $ h $ h $ h (czas + ms). Próbowałem pokazać, jak można to zrobić z zestawem zmiennych, które mogą działać bez linii zachęty. Zasadniczo próbowałem zrobić tę ustawioną datę =% RRRR %% MM %% DD%, ale używam tutaj Linuksa i kompiluję skrypt na SciTE, więc nie wiem, czy to działa. Przepraszam, jeśli to nie działa.
Secko

Zapomniałem dodać, $ _ to nowa linia.
Secko

1
Spróbuj także @prompt // $ d $ _ $ t $ h $ h $ h $ h $ h $ h //
Secko

Zauważ, że to również nie jest niezależne od lokalizacji. Data jest sformatowana zgodnie z bieżącym ustawieniem kultury, w moim przypadku DD.MM.RRRR (dla języka niemieckiego).
Hannobo

2

Złożyłem mały program w C, aby wydrukować aktualny znacznik czasu (bezpieczny dla języka, bez złych znaków ...). Następnie używam polecenia FOR, aby zapisać wynik w zmiennej środowiskowej:

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

Oto link:

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


2

Wiem, że ten wątek jest stary, ale chcę go tutaj dodać, ponieważ pomogło mi to dużo próbować to wszystko rozgryźć i jest czyste. Fajną rzeczą w tym jest to, że możesz umieścić to w pętli dla pliku wsadowego, który zawsze działa. Dziennik czasu działania serwera czy coś w tym stylu. W każdym razie do tego go używam. Mam nadzieję, że kiedyś komuś to pomoże.

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

Było to przydatne dla mnie, chociaż w pliku ".cmd" dwukropki w zmiennej "FreshTime" powodowały błędy, gdy były używane do nazwy pliku w mojej linii cmdline "robocopy": ERROR : Invalid Parameter #12 : "/LOG:C:\opt\Sync_08.10.2020_16:27:39.log"Zamiast tego użyłem myślników:set FreshTime=%hour%-%min%-%secs%
netdesignate

2

Możesz po prostu wykryć aktualny format lokalny i uzyskać datę w swoim formacie, na przykład:

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

Wiem, że to stary post, ale jest O wiele prostsza odpowiedź (chociaż może działa tylko w nowszych wersjach systemu Windows). Po prostu użyj parametru / t dla poleceń DATA i CZAS, aby wyświetlić tylko datę lub godzinę i nie monitować o ich ustawienie, na przykład:

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

1

1) Możesz pobrać coreutils GNU z datą GNU

2) możesz użyć VBScript , który ułatwia manipulowanie datami w systemie 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

Uruchom skrypt jako:

c:\test> cscript /nologo myscript.vbs

0

Działa to dobrze z (moim) niemieckim językiem, powinno być możliwe dostosowanie go do twoich potrzeb ...

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%działa również w portugalskiej lokalizacji! Mam na myśli RRRRMMDD
Fernando Fabreti

0

W przypadku dużych plików zip do wdrożenia używam kwadransa. Nikt inny na tej stronie nie wspomniał o tym wcześniej, więc umieszczę tutaj mój mały skrypt:

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"

Nie zeruje jeszcze kwadrans od północy do 5 rano, ale nadal sprawia, że ​​możesz mieć stemplowane zwolnienie wiele razy dziennie z kilkoma kolizjami.

Mam nadzieję, że to pomoże.


0

wykorzystał sugestię Martina z niewielką poprawką, aby dodać znacznik czasu do nazwy pliku:

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

Na 23.10.2019 10:17:21 Wynik to:

20191023_10-17-21-rsync2.log

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.