windows - variable - Crear un nombre de archivo como una marca de tiempo en un trabajo por lotes
cmd date format ddmmyyyy (15)
Tenemos un trabajo por lotes que se ejecuta todos los días y copia un archivo en una carpeta de recogida. También quiero tomar una copia de ese archivo y soltarlo en una carpeta de archivo con el nombre del archivo
yyyy-MM-dd.log
¿Cuál es la forma más fácil de hacer esto en un trabajo por lotes de Windows?
Básicamente estoy buscando un equivalente de este comando de Unix:
cp source.log `date +%F`.log
1) Puedes descargar GNU coreutils que viene con fecha de GNU
2) puede usar VBScript , lo que facilita la manipulación de la fecha en 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
Ejecute el script como:
c:/test> cscript /nologo myscript.vbs
Aquí hay una solución independiente de configuración regional (copie en un archivo llamado 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%
Puse todos mis scripts .cmd en la misma carpeta (% SCRIPTROOT%); cualquier script que necesite valores de fecha / hora llamará a SetDateTimeComponents.cmd como en el siguiente ejemplo:
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%
Como muestra el ejemplo, puede llamar a SetDateTimeComponents.cmd cada vez que necesite actualizar los valores de fecha / hora. Ocultar el script de análisis de tiempo en su propio archivo SetDateTimeComponents.cmd es una buena manera de ocultar los detalles desagradables y, lo que es más importante, evitar los errores tipográficos.
Arreglé un pequeño programa en C para imprimir la marca de tiempo actual (seguro para la configuración regional, sin malos caracteres ...). Luego, utilizo el comando FOR para guardar el resultado en una variable de entorno:
:: 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"
Aquí hay un enlace:
Con frecuencia uso esto y pongo todo en un solo comando de copia. La siguiente copia example.txt como example_YYYYMMDD_HHMMSS.txt y, por supuesto, puede modificarla para adaptarla a su formato preferido. Las comillas solo son necesarias si hay espacios en la especificación de archivos. Si desea reutilizar la misma fecha / marca de tiempo exacta, deberá almacenarla en una variable.
copy "{path}/example.txt" "{path}/_%date:~10,4%%date:~4,2%%date:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.txt"
Crea un archivo con la fecha actual como nombre de archivo (ej. 2008-11-08.dat)
echo hello > %date%.dat
Con la fecha actual pero sin el "-" (ej. 20081108.dat)
echo hello > %date:-=%.dat
Debido a que la idea de dividir %DATE%
y %TIME%
y mezclarlos nuevamente parece frágil en el mejor de los casos, he aquí una alternativa que utiliza un delineador 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
La referencia para get-date
está here , con opciones de formato para .NET-style y UNIX-style.
Esto asegurará que la salida sea un valor de 2 dígitos ... puede reorganizar la salida a su gusto y probar desactivándola de la sección de diagnóstico. ¡Disfrutar!
(Pedí mucho de esto en otros foros ...)
:: ------------------ 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%
Esto funcionó para mí y era una solución segura para el nombre de archivo (aunque genera un formato MM-dd-YYYY):
C:/ set SAVESTAMP=%DATE:/=-%@%TIME::=-%
C:/ set SAVESTAMP=%SAVESTAMP: =%
C:/ set SAVESTAMP=%SAVESTAMP:,=.%.jpg
C:/ echo %SAVESTAMP%
[email protected]
El primer comando toma una FECHA y reemplaza /
con -
, toma el TIEMPO y reemplaza :
con -
, y los combina con el formato FECHA @ HORA. La segunda declaración de set
elimina cualquier espacio, y el tercer set
reemplaza ,
con .
y agrega la extensión .jpg
.
El código anterior se utiliza en un pequeño script que extrae imágenes de una cámara IP de seguridad para su posterior procesamiento:
: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
Esto funciona bien con (mi) configuración regional alemana, debería ser posible ajustarlo a sus necesidades ...
forfiles /p *PATH* /m *filepattern* /c "cmd /c ren @file
%DATE:~6,4%%DATE:~3,2%%DATE:~0,2%_@file"
Para la configuración regional francesa (Francia) ÚNICAMENTE , tenga cuidado porque /
aparece en la fecha:
echo %DATE%
08/09/2013
Para nuestro problema de archivo de registro, esta es mi propuesta SOLAMENTE para la configuración regional en francés :
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%
Sé que esta es una publicación anterior, pero hay una respuesta mucho más simple (aunque tal vez solo funciona en versiones más nuevas de Windows). Simplemente use el parámetro / t para los comandos DATE y TIME dos para mostrar solo la fecha o la hora y no solicitarle que lo configure, como este:
@echo off
echo Starting test batch file > testlog.txt
date /t >> testlog.txt
time /t >> testlog.txt
Sé que este hilo es viejo, pero solo quiero agregar esto aquí porque me ayudó mucho tratando de resolver todo esto y está limpio. Lo bueno de esto es que podrías ponerlo en un bucle para un archivo por lotes que siempre se está ejecutando. Registro de tiempo de actividad del servidor o algo así. De eso es lo que lo uso para todos modos. Espero que esto ayude a alguien algún día.
@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%
Simplemente puede detectar el formato local actual y puede obtener la fecha en su formato, por ejemplo:
::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
Tal vez esto puede ayudar:
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%
CP source.log %DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%.log
Pero depende de la configuración regional. No estoy seguro de si %DATE%
está localizado, o depende del formato especificado para la fecha corta en Windows.
Aquí hay una forma independiente de configuración regional para extraer la fecha actual de esta respuesta , pero depende de WMIC
y 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