Fecha y hora de comando de lote en nombre de archivo

Estoy comprimiendo archivos usando WinZip en la línea de comando. Como archivamos todos los días, bash agregar fecha y hora a estos archivos para que se genere uno nuevo cada vez.

Uso lo siguiente para generar un nombre de archivo. Copie y péguelo en su línea de comando, y debería ver un nombre de archivo con un componente de fecha y hora.

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

Salida

 Archive_20111011_ 93609.zip 

Sin embargo, mi problema es AM vs PM . La marca de tiempo de AM me da el tiempo 9 (con un espacio en blanco adelantado) frente a 10 ocupando naturalmente los dos espacios.

Supongo que mi problema se extenderá a los primeros nueve días, primeros 9 meses, etc. también.

¿Cómo soluciono esto para que se incluyan los ceros Archive_20111011_093609.zip lugar de espacios en blanco Archive_20111011_093609.zip así que obtengo Archive_20111011_093609.zip ?

Otra solución:

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

Le dará (¡independientemente de la configuración regional!):

  20130802203023.304000+120 ( YYYYMMDDhhmmss.+/- ) 

Desde aquí, es fácil:

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

Para la solicitud de Logan del mismo formato de salida para el “cambio de fecha y hora” de un archivo:

 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 un poco más complicado, porque solo funciona con rutas completas, wmic espera que las barras diagonales se dupliquen y se tenga que escapar = el primero. El segundo está protegido por comillas circundantes.

Extraiga la hora, busque un espacio principal, si lo encuentra reemplace con un cero;

 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 

Debes buscar; simplemente puede reemplazar todos los espacios con cero set hr=%hr: =0%jeb Oct 11 ’11 at 14:16

Así que lo hice:

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

Luego use %hr% dentro de la cadena que está formateando para obtener siempre una hora de dos dígitos.

(El comentario de Jeb en la respuesta más popular funcionó lo mejor para mí y es el más simple. Lo vuelvo a publicar aquí para hacerlo más obvio para los futuros usuarios).

Como Vicky ya señaló, %DATE% y %TIME% devuelven la fecha y la hora actuales usando los formatos cortos de fecha y hora que son completamente personalizables.

Un usuario puede configurar su sistema para devolver Fri040811 08.03PM mientras que otro usuario puede elegir 08/04/2011 20:30.

Es una pesadilla completa para un progtwigdor de BAT.

Cambiar el formato a un formato firme puede solucionar el problema, siempre que restaure el formato anterior antes de abandonar el archivo BAT. Pero puede estar sujeto a condiciones desagradables y complicar la recuperación en archivos BAT cancelados.

Afortunadamente, hay una alternativa.

Puede usar WMIC, en su lugar. WMIC Path Win32_LocalTime Get Day,Hour,Minute,Month,Second,Year /Format:table devuelve la fecha y la hora de forma invariable. Muy conveniente para analizarlo directamente con un comando FOR /F

Entonces, juntando las piezas, intente esto como punto de partida …

 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 ) 

Encontré la mejor solución para mí, después de leer todas sus respuestas:

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

Si AM, obtengo 20160915_ 150101 (con un espacio y tiempo destacado).

Si PM obtengo 20160915_2150101 .

Puede agregar ceros a una variable (valor hasta 99) como este en lote: IF 1%Var% LSS 100 SET Var=0%Var%

Por lo tanto, necesitaría analizar los componentes de fecha y hora en variables separadas, tratarlos a todos de esta manera y luego volver a concatenarlos para crear el nombre del archivo.

Sin embargo, su método subyacente para analizar la fecha y la hora depende de la configuración regional del sistema. Si está contento de que su código no sea portátil para otras máquinas, probablemente esté bien, pero si espera que funcione en diferentes contextos internacionales, necesitará un enfoque diferente, por ejemplo, leyendo la configuración del registro:

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

(Este último controla si hay un cero inicial en las horas, pero no las fechas, hasta donde yo sé).

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

Esto toma MB5L.txt y lo comprime en ziptest20120204.zip si se ejecuta el 4 de febrero de 2012

Tu pregunta parece estar resuelta, pero …

No estoy seguro si tomas la solución correcta para tu problema.
Supongo que intentas comprimir cada día el código del proyecto real.

Es posible con ZIP y 1980 esta era una buena solución, pero hoy debería usar un sistema de repository, como subversión o git o …, pero no un archivo comprimido.

Ok, tal vez podría ser que estoy equivocado.

De la respuesta anterior, he hecho una función lista para usar.

Validado con ajustes locales franceses.

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

Me doy cuenta de que esta es una pregunta discutible para el OP, pero acabo de elaborar esto, y estoy un poco orgulloso de mí mismo por pensar de manera innovadora.

Descargue gawk para Windows en http://gnuwin32.sourceforge.net/packages/gawk.htm … Luego es un trazador de líneas único, sin toda esa syntax discontinua de DOS, donde se necesitan seis bucles FOR para dividir las cadenas (WTF) “¡Eso es realmente MUY ENOJADO Y TRISTE! … en mi humilde opinión, por supuesto)

Si ya conoces a C, C ++, Perl o Ruby, entonces recoger AWK (que hereda de los dos anteriores, y contribuye significativamente a los dos últimos) es una pieza del proverbial PASTEL !!!

El comando DOS Batch:

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

Huellas dactilares:

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

Ahora que no es toda la historia … Voy a ser perezoso y codificar el rest de mi nombre de archivo de registro en la statement de printf, porque es simple … Pero si alguien sabe cómo configurar un % NOW% variable a la salida de AWK (edificando las agallas de una función “genérica” ​​ahora) entonces soy todo oídos.


EDITAR:

Una búsqueda rápida en Desbordamiento de stack llenó esa última pieza del rompecabezas, el equivalente en lotes de Bash backticks .

Por lo tanto, estas tres líneas de lote de DOS:

 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% 

Produce:

 20120904-114434 

Así que ahora puedo incluir una fecha y hora en el nombre del archivo de registro producido por mi secuencia de comandos de instalación de SQL Server (2005+) así:

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

Y soy una campista feliz otra vez (excepto que la vida todavía era mucho más fácil en Unix).

Un espacio es legal en los nombres de archivo. Si coloca la ruta y el nombre de archivo entre comillas, puede que simplemente se active. Esto es lo que estoy usando en un archivo por lotes:

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

No importa si hay espacios en% filename%.