it-swarm.com.de

Datum und Uhrzeit des Stapelbefehls im Dateinamen

Ich komprimiere Dateien mit WinZip in der Befehlszeile. Da wir täglich archivieren, versuche ich, Datum und Uhrzeit zu diesen Dateien hinzuzufügen, damit jedes Mal ein neues erstellt wird.

Ich benutze folgendes, um einen Dateinamen zu generieren. Kopieren Sie es in Ihre Befehlszeile und Sie sollten einen Dateinamen mit einer Datums- und Zeitkomponente sehen.

echo Archive_%date:~-4,4%%date:~-10,2%%date:~-7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.Zip

Ausgabe

Archive_20111011_ 93609.Zip

Mein Problem ist jedoch AM vs PM. Der AM-Zeitstempel gibt mir die Zeit 9 (mit einem führenden Leerzeichen) gegen 10, wobei die beiden Leerzeichen natürlich genommen werden. 

Ich denke, meine Ausgabe wird sich auch auf die ersten neun Tage, die ersten neun Monate usw. erstrecken.

Wie behebe ich das so, dass führende Nullen anstelle führender Leerzeichen eingefügt werden, damit ich Archive_20111011_093609.Zip bekomme?

59
Raj More

Eine andere Lösung:

for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set datetime=%%I

Es gibt Ihnen (unabhängig von den Ländereinstellungen!):

  20130802203023.304000+120
( YYYYMMDDhhmmss.<milliseconds><always 000>+/-<timedifference to UTC>  )

Von hier ist es einfach:

set datetime=%datetime:~0,8%-%datetime:~8,6%
20130802-203023

Für Logans Anforderung für dasselbe Ausgabeformat für das "Datum-Uhrzeit-Ändern" einer Datei:

for %%F in (test.txt) do set file=%%~fF
for /f "tokens=2 delims==" %%I in ('wmic datafile where name^="%file:\=\\%" get lastmodified /format:list') do set datetime=%%I
echo %datetime%

Es ist etwas komplizierter, da es nur mit vollständigen Pfaden funktioniert. wmic erwartet, dass die umgekehrten Schrägstriche verdoppelt werden und der = mit Escapezeichen versehen wird (der erste. Der zweite ist durch Anführungszeichen geschützt).

54
Stephan

Extrahieren Sie die Stunde und suchen Sie nach einem führenden Leerzeichen.

set hr=%time:~0,2%
if "%hr:~0,1%" equ " " set hr=0%hr:~1,1%
echo Archive_%date:~-4,4%%date:~-10,2%%date:~-7,2%_%hr%%time:~3,2%%time:~6,2%.Zip
54
Alex K.

Sie sollten suchen; Sie können einfach alle Leerzeichen durch Null ersetzen set hr=%hr: =0% - jeb11. Oktober 11 um 14:16

So tat ich:

set hr=%time:~0,2%
set hr=%hr: =0%

Verwenden Sie dann %hr% in der Zeichenfolge, die Sie formatieren, um immer eine zweistellige Stunde zu erhalten.

(Jebs Kommentar unter der populärsten Antwort hat am besten für mich funktioniert und ist der einfachste. Ich wiederhole ihn hier, um ihn für zukünftige Benutzer deutlicher zu machen.)

19
WxGuy

Wie bereits erwähnt, geben %DATE% und %TIME% das aktuelle Datum und die aktuelle Uhrzeit unter Verwendung der kurzen Datums- und Zeitformate zurück, die vollständig (endlos) anpassbar sind.

Ein Benutzer kann sein System so konfigurieren, dass Fri040811 08.03 PM zurückgegeben wird, während ein anderer Benutzer den 08/04/2011 20:30 wählen kann.

Es ist ein absoluter Albtraum für einen BAT-Programmierer.

Das Ändern des Formats in ein festes Format kann das Problem möglicherweise beheben, sofern Sie das vorherige Format wiederherstellen, bevor Sie die BAT-Datei verlassen. Es kann jedoch unangenehmen Rennbedingungen unterliegen und die Wiederherstellung in abgebrochenen BAT-Dateien erschweren.

Zum Glück gibt es eine Alternative.

Sie können stattdessen WMIC verwenden. WMIC Path Win32_LocalTime Get Day,Hour,Minute,Month,Second,Year /Format:table gibt Datum und Uhrzeit auf unveränderliche Weise zurück. Sehr praktisch, um es direkt mit einem FOR /F-Befehl zu analysieren.

Also, füge die Teile zusammen und versuche dies als Ausgangspunkt ...

SETLOCAL enabledelayedexpansion
FOR /F "skip=1 tokens=1-6" %%A IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Month^,Second^,Year /Format:table') DO (
  SET /A FD=%%F*1000000+%%D*100+%%A
  SET /A FT=10000+%%B*100+%%C
  SET FT=!FT:~-4!
  ECHO Archive_!FD!_!FT!.Zip
 )
14
PA.

Ich habe die beste Lösung für mich gefunden, nachdem ich alle Ihre Antworten gelesen hatte:

set t=%date%_%time%
set d=%t:~10,4%%t:~7,2%%t:~4,2%_%t:~15,2%%t:~18,2%%t:~21,2%
echo hello>"Archive_%d%"

Bei AM bekomme ich 20160915_ 150101 (mit führendem Leerzeichen und Zeit).

Wenn PM, bekomme ich 20160915_2150101.

8
Nesar

Sie können führende Variablen (Wert bis zu 99) wie folgt im Stapel hinzufügen: IF 1%Var% LSS 100 SET Var=0%Var%

Sie müssen also Ihre Datums- und Zeitkomponenten in separate Variablen parsen, sie alle so behandeln und sie dann wieder zusammenfügen, um den Dateinamen zu erstellen.

Ihre zugrunde liegende Methode zum Analysieren von Datum und Uhrzeit hängt jedoch von den Systemeinstellungen für das Gebietsschema ab. Wenn Sie sich darüber freuen, dass Ihr Code nicht auf andere Computer übertragen werden kann, ist dies wahrscheinlich in Ordnung. Wenn Sie jedoch davon ausgehen, dass er in verschiedenen internationalen Zusammenhängen funktioniert, benötigen Sie einen anderen Ansatz, beispielsweise durch Lesen der Registrierungseinstellungen:

HKEY_CURRENT_USER\Control Panel\International\iDate
HKEY_CURRENT_USER\Control Panel\International\iTime
HKEY_CURRENT_USER\Control Panel\International\iTLZero

(Das letzte steuert, ob es eine führende Null zu Zeiten gibt, aber keine Daten, soweit ich weiß). 

4
Vicky
@For /F "tokens=1,2,3,4 delims=/ " %%A in ('Date /t') do @(

Set DayW=%%A

Set Day=%%B

Set Month=%%C


Set Year=%%D


Set All=%%D%%B%%C
)
"C:\Windows\CWBZIP.EXE" "c:\transfer\ziptest%All%.Zip" "C:\transfer\MB5L.txt"

Dies erfordert MB5L.txt und komprimiert es zu ziptest20120204.Zip, wenn es am 4. Februar 2012 ausgeführt wird

3
user1189773

Ihre Frage scheint gelöst zu sein, aber ...

Ich bin mir nicht sicher, ob Sie die richtige Lösung für Ihr Problem finden.
Ich denke, Sie versuchen, jeden Tag den aktuellen Projektcode zu komprimieren.

Mit Zip und 1980 ist dies möglich. Dies war eine gute Lösung, aber heute sollten Sie ein Repository-System wie Subversion oder git oder ... verwenden, jedoch keine Zip-Datei.

Ok, vielleicht kann ich falsch liegen.

2
jeb

Aus der obigen Antwort habe ich eine gebrauchsfertige Funktion erstellt.

Bestätigt mit französischen lokalen Einstellungen.

:::::::: PROGRAM ::::::::::

call:genname "my file 1.txt"
echo "%newname%"
call:genname "my file 2.doc"
echo "%newname%"

echo.&pause&goto:eof
:::::::: FUNCTIONS :::::::::

:genname
    set d1=%date:~-4,4%
    set d2=%date:~-10,2%
    set d3=%date:~-7,2%
    set t1=%time:~0,2%
    ::if "%t1:~0,1%" equ " " set t1=0%t1:~1,1%
    set t1=%t1: =0%
    set t2=%time:~3,2%
    set t3=%time:~6,2%
    set filename=%~1
    set newname=%d1%%d2%%d3%_%t1%%t2%%t3%-%filename%
goto:eof
2
user2757848

Mir ist klar, dass dies eine umstrittene Frage an das OP ist, aber ich habe es gerade gebraut, und ich bin ein bisschen stolz auf mich, wenn ich über den Tellerrand hinaus denke.

Laden Sie gawk für Windows unter http://gnuwin32.sourceforge.net/packages/gawk.htm ... herunter. Dann ist es ein Einzeiler ohne all die klobige DOS-Batch-Syntax, bei der es sechs dauert FOR-Loops, um die Saiten zu teilen (WTF? Das ist wirklich wirklich schlecht und schlecht! ... IMHO natürlich)

Wenn Sie bereits C, C++, Perl oder Ruby kennen, dann ist das Aufnehmen von AWK (das von den ersten beiden erbt und wesentlich zu den letzten beiden beiträgt) ein Teil des sprichwörtlichen CAKE !!!

Der DOS-Stapelbefehl:

echo %DATE% %TIME% && echo %DATE% %TIME% | gawk -F"[ /:.]" "{printf(""""%s%02d%02d-%02d%02d%02d\n"""", $4, $3, $2, $5, $6, $7);}"

Drucke:

Tue 04/09/2012 10:40:38.25
20120904-104038

Nun, das ist nicht die ganze Geschichte ... Ich werde nur faul sein und den Rest meines Protokolldateinamens in der printf-Anweisung hartcodieren, weil es einfach ist ... Aber wenn jemand weiß, wie man ein setzt % JETZT% Variable an AWKs Ausgabe (yeilding der "generic" Funktion jetzt), dann bin ich ganz Ohr.


EDIT:

Eine schnelle Suche im Stapelüberlauf füllte das letzte Stück des Puzzles aus: Stapeläquivalent für Bash-Backticks.

Also, diese drei Zeilen von DOS Batch:

echo %DATE% %TIME% | awk -F"[ /:.]" "{printf(""""%s%02d%02d-%02d%02d%02d\n"""", $4, $3, $2, $5, $6, $7);}" >%temp%\now.txt
set /p now=<%temp%\now.txt
echo %now%

Produzieren:

20120904-114434

So kann ich jetzt eine datetime in den Namen der von meinem SQL Server-Installationsskript (2005+) erzeugten Protokolldatei aufnehmen:

sqlcmd -S .\SQLEXPRESS -d MyDb -e -i MyTSqlCommands.sql >MyTSqlCommands.sql.%now%.log

Und ich bin wieder ein fröhlicher Camper (außer das Leben war auf Unix noch viel einfacher).

0
corlettk

Wie bereits erwähnt, sind die Datums- und Zeitformate von %DATE% und %TIME% (sowie date /T und time /T) vom Gebietsschema abhängig, sodass das aktuelle Datum extrahiert wird und Zeit ist immer ein Albtraum, und es ist unmöglich, eine Lösung zu finden, die mit allen möglichen Formaten funktioniert, da es kaum Formatbeschränkungen gibt.


Es gibt jedoch ein anderes Problem mit einem Code wie dem folgenden (nehmen wir ein Datumsformat wie MM/DD/YYYY und ein 12-Stunden-Zeitformat wie h:mm:ss.ff ap an, wobei ap entweder AM ist. oder PM und ff sind Sekundenbruchteile):

rem // Resolve AM/PM time:
set "HOUR=%TIME:~,2%"
if "%TIME:~-2%" == "PM" if %HOUR% lss 12 set /A "HOUR+=12"
if "%TIME:~-2%" == "AM" if %HOUR% equ 12 set /A "HOUR-=12"
rem // Left-zero-pad hour:
set "HOUR=0%HOUR%"
rem // Build and display date/time string:
echo %DATE:~-4,4%%DATE:~0,2%%DATE:~3,2%_%HOUR:~-2%%TIME:~3,2%%TIME:~6,2%

Jede Instanz von %DATE% und %TIME% gibt den zum Zeitpunkt der Erweiterung vorhandenen Datums- oder Zeitwert zurück. Daher kann der erste Ausdruck %DATE% oder %TIME% einen anderen Wert als der zurückgeben die folgenden (Sie können dies beweisen, wenn Sie einen langen String mit einer großen Menge solcher Ausdrücke ausgeben, vorzugsweise %TIME%).

Sie können den oben genannten Code so verbessern, dass er eine einzelne Instanz von %DATE% und %TIME% enthält:

rem // Store current date and time once in the same line:
set "CURRDATE=%DATE%" & set "CURRTIME=%TIME%"
rem // Resolve AM/PM time:
set "HOUR=%CURRTIME:~,2%"
if "%CURRTIME:~-2%" == "PM" if %HOUR% lss 12 set /A "HOUR+=12"
if "%CURRTIME:~-2%" == "AM" if %HOUR% equ 12 set /A "HOUR-=12"
rem // Left-zero-pad hour:
set "HOUR=0%HOUR%"
rem // Build and display date/time string:
echo %CURRDATE:~-4,4%%CURRDATE:~0,2%%CURRDATE:~3,2%_%HOUR:~-2%%CURRTIME:~3,2%%CURRTIME:~6,2%

Die zurückgegebenen Werte in %DATE% und %TIME% können jedoch unterschiedliche Tage widerspiegeln, wenn sie um Mitternacht ausgeführt werden.

Die einzige Möglichkeit, in %CURRDATE% und %CURRTIME% denselben Tag zu haben, ist die folgende:

rem // Store current date and time once in the same line:
set "CURRDATE=%DATE%" & set "CURRTIME=%TIME%"
rem // Resolve AM/PM time:
set "HOUR=%CURRTIME:~,2%"
if "%CURRTIME:~-2%" == "PM" if %HOUR% lss 12 set /A "HOUR+=12"
if "%CURRTIME:~-2%" == "AM" if %HOUR% equ 12 set /A "HOUR-=12"
rem // Fix date/time midnight discrepancy:
if not "%CURRDATE%" == "%DATE%" if %CURRTIME:~0,2% equ 0 set "CURRDATE=%DATE%"
rem // Left-zero-pad hour:
set "HOUR=0%HOUR%"
rem // Build and display date/time string:
echo %CURRDATE:~-4,4%%CURRDATE:~0,2%%CURRDATE:~3,2%_%HOUR:~-2%%CURRTIME:~3,2%%CURRTIME:~6,2%

Natürlich ist das Auftreten des beschriebenen Problems ziemlich unwahrscheinlich, aber irgendwann wird es passieren und seltsame unerklärliche Fehler verursachen.


Das beschriebene Problem kann nicht mit den Ansätzen auftreten, die auf dem Befehl wmic basieren, wie in answer by user Stephan und in answer beschrieben by user PA. , daher empfehle ich dringend, einen von ihnen zu wählen. Der einzige Nachteil von wmic ist, dass es viel langsamer ist.

0
aschipfl

Ein Leerzeichen ist in Dateinamen zulässig. Wenn Sie Ihren Pfad und Dateinamen in Anführungszeichen setzen, kann es nur fliegen. Was ich in einer Batch-Datei verwende:

svnadmin hotcopy "C:\SourcePath\Folder" "f:\DestPath\Folder%filename%"

Es spielt keine Rolle, ob in% filename% Leerzeichen vorhanden sind. 

0
Marty