Establecer una variable de archivo de lote de Windows para el día de la semana

Tengo un archivo de lote de Windows que se ejecuta a diario. Desea registrar datos en un archivo y desea rotarlo (es decir, tener como máximo los últimos 7 días de datos).

Miró los comandos DATE y DELIMS – No se puede encontrar una solución.

¿Existe una solución simple para crear un nombre de archivo que contenga el día de la semana, es decir, 0 para el lunes, etc.

O tengo que recurrir a un script de shell mejor.

%DATE% no es tu amigo. Debido a que la variable de entorno %DATE% (y el comando DATE ) devuelve la fecha actual usando el formato de fecha corta de Windows que se puede personalizar completamente e infinitamente. Un usuario puede configurar el sistema para que devuelva 07/06/2012, mientras que otro puede elegir Fri060712. Usar %DATE% es una pesadilla completa para un progtwigdor BAT.

Hay dos enfoques posibles para resolver este problema:

  1. Puede tener la tentación de cambiar temporalmente el formato de fecha corta, cambiando la configuración regional en el valor de registro HKCU\Control Panel\International\sShortDate , a su formato reconocible. Luego, ingrese %DATE% para obtener la fecha en el formato que desee; y finalmente restaurar el formato al formato de usuario original. Algo como esto

     reg copy "HKCU\Control Panel\International" "HKCU\Control Panel\International-Temp" /f >nul reg add "HKCU\Control Panel\International" /v sShortDate /d "ddd" /f >nul set DOW=%DATE% reg copy "HKCU\Control Panel\International-Temp" "HKCU\Control Panel\International" /f >nul 

    pero este método tiene dos problemas:

    • manipula un valor de registro global para sus propósitos locales específicos, por lo que puede interferir con otros procesos o tareas de usuario que al mismo tiempo consulten la fecha en formato de fecha corta, incluyéndose a sí mismo si se ejecuta simultáneamente.

    • y devuelve el día de tres letras de la semana en el idioma local que puede ser diferente en diferentes sistemas o diferentes usuarios.

  2. use WMIC Win32_LocalTime , que devuelve la fecha de manera conveniente para analizarlo directamente con un comando FOR .

     FOR /F "skip=1" %%A IN ('WMIC Path Win32_LocalTime Get DayOfWeek' ) DO ( set DOW=%%A ) 

    este es el método que recomiendo

algunas otras formas:

1. Robocopy no está disponible en XP, pero se puede descargar desde el kit de herramientas de recursos de win 2003.También puede depender de la localización:

 @echo off setlocal for /f "skip=8 tokens=2,3,4,5,6,7,8 delims=: " %%D in ('robocopy /l * \ \ /ns /nc /ndl /nfl /np /njh /XF * /XD *') do ( set "dow=%%D" set "month=%%E" set "day=%%F" set "HH=%%G" set "MM=%%H" set "SS=%%I" set "year=%%J" ) echo Day of the week: %dow% endlocal 

2. MAKECAB : funciona en todas las máquinas de Windows (pero crea un pequeño archivo temporal). Función proporcionada por carlos:

 @Echo Off Call :GetDate.Init Rem :GetDate.Init should be called one time in the code before call to :Getdate Call :GetDate Echo weekday:%weekday% Goto :EOF :GetDate.Init Set /A "jan=1,feb=2,mar=3,apr=4,may=5,jun=6,jul=7,aug=8,sep=9,oct=10,nov=11,dec=12" Set /A "mon=1,tue=2,wed=3,thu=4,fri=5,sat=6,sun=7" ( Echo .Set InfHeader="" Echo .Set InfSectionOrder="" Echo .Set InfFooter="%%2" Echo .Set InfFooter1="" Echo .Set InfFooter2="" Echo .Set InfFooter3="" Echo .Set InfFooter4="" Echo .Set Cabinet="OFF" Echo .Set Compress="OFF" Echo .Set DoNotCopyFiles="ON" Echo .Set RptFileName="NUL" ) >"%Temp%\~foo.ddf" Goto :Eof :GetDate Set "tf=%Temp%\~%random%" Makecab /D InfFileName="%tf%" /F "%Temp%\~foo.ddf" >NUL For /F "usebackq tokens=1-7 delims=: " %%a In ("%tf%") Do ( Set /A "year=%%g,month=%%b,day=1%%c-100,weekday=%%a" Set /A "hour=1%%d-100,minute=1%%e-100,second=1%%f-100") Del "%tf%" >NUL 2>&1 Goto :Eof 

3. W32TM : utiliza conmutadores de comando introducidos en Vista, por lo que no funcionará en Windows 2003 / XP:

 @echo off setlocal call :w32dow day_ow echo %day_ow% pause exit /b 0 endlocal :w32dow [RrnVar] setlocal rem :: prints the day of the week rem :: works on Vista and above rem :: getting ansi date ( days passed from 1st jan 1601 ) , timer server hour and current hour FOR /F "tokens=4,5 delims=:( " %%D in ('w32tm /stripchart /computer:localhost /samples:1 /period:1 /dataonly /packetinfo^|find "Transmit Timestamp:" ') do ( set "ANSI_DATE=%%D" set "TIMESERVER_HOURS=%%E" ) set "LOCAL_HOURS=%TIME:~0,2%" if "%TIMESERVER_HOURS:~0,1%0" EQU "00" set TIMESERVER_HOURS=%TIMESERVER_HOURS:~1,1% if "%LOCAL_HOURS:~0,1%0" EQU "00" set LOCAL_HOURS=%LOCAL_HOURS:~1,1% set /a OFFSET=TIMESERVER_HOURS-LOCAL_HOURS rem :: day of the week will be the modulus of 7 of local ansi date +1 rem :: we need need +1 because Monday will be calculated as 0 rem :: 1st jan 1601 was Monday rem :: if abs(offset)>12 we are in different days with the time server IF %OFFSET%0 GTR 120 set /a DOW=(ANSI_DATE+1)%%7+1 IF %OFFSET%0 LSS -120 set /a DOW=(ANSI_DATE-1)%%7+1 IF %OFFSET%0 LEQ 120 IF %OFFSET%0 GEQ -120 set /a DOW=ANSI_DATE%%7+1 rem echo Day of the week: %DOW% endlocal & if "%~1" neq "" (set "%~1=%DOW%") else echo %DOW% 

4. híbrido de .bat / jscript (se debe guardar como .bat):

  @if (@x)==(@y) @end /***** jscript comment ****** @echo off for /f %%d in ('cscript //E:JScript //nologo "%~f0"') do echo %%d exit /b 0 ***** end comment *********/ WScript.Echo((new Date).getDay()); 

5. híbrido de .bat / vbscript (se debe guardar como .bat)

  :sub echo(str) :end sub echo off '>nul 2>&1|| copy /Y %windir%\System32\doskey.exe '.exe >nul '& echo/ '& for /f %%w in ('cscript /nologo /E:vbscript %~dpfn0') do echo day of the week %%w '& echo/ '& del /q "'.exe" >nul 2>&1 '& exit /b WScript.Echo Weekday(Date) WScript.Quit 

6. powershell se puede descargar desde microsoft. Disponible de forma predeterminada en todos los formatos win7 y superior:

 @echo off setlocal for /f %%d in ('"powershell (Get-Date).DayOfWeek.Value__"') do set dow=%%d echo day of the week : %dow% endlocal 

7. WMIC ya se usó como respuesta, pero solo quiero tener una referencia completa. Y con despejado:

 @echo off setlocal for /f "delims=" %%a in ('wmic path win32_localtime get dayofweek /format:list ') do for /f "delims=" %%d in ("%%a") do set %%d echo day of the week : %dayofweek% endlocal 

9. Selfcompiled jscript.net (se debe guardar como .bat ):

 @if (@X)==(@Y) @end /****** silent line that start jscript comment ****** @echo off :::::::::::::::::::::::::::::::::::: ::: compile the script :::: :::::::::::::::::::::::::::::::::::: setlocal if exist "%~n0.exe" goto :skip_comstacktion set "frm=%SystemRoot%\Microsoft.NET\Framework\" :: searching the latest installed .net framework for /f "tokens=* delims=" %%v in ('dir /b /s /a:d /o:-n "%SystemRoot%\Microsoft.NET\Framework\v*"') do ( if exist "%%v\jsc.exe" ( rem :: the javascript.net compiler set "jsc=%%~dpsnfxv\jsc.exe" goto :break_loop ) ) echo jsc.exe not found && exit /b 0 :break_loop call %jsc% /nologo /out:"%~n0.exe" "%~dpsfnx0" :::::::::::::::::::::::::::::::::::: ::: end of comstacktion :::: :::::::::::::::::::::::::::::::::::: :skip_comstacktion "%~n0.exe" exit /b 0 ****** end of jscript comment ******/ import System; import System.IO; var dt=DateTime.Now; Console.WriteLine(dt.DayOfWeek); 
 @ECHO OFF REM GET DAY OF WEEK VIA DATE TO JULIAN DAY NUMBER CONVERSION REM ANTONIO PEREZ AYALA REM GET MONTH, DAY, YEAR VALUES AND ELIMINATE LEFT ZEROS FOR /F "TOKENS=1-3 DELIMS=/" %%A IN ("%DATE%") DO SET /A MM=10%%A %% 100, DD=10%%B %% 100, YY=%%C REM CALCULATE JULIAN DAY NUMBER, THEN DAY OF WEEK IF %MM% LSS 3 SET /A MM+=12, YY-=1 SET /AA=YY/100, B=A/4, C=2-A+B, E=36525*(YY+4716)/100, F=306*(MM+1)/10, JDN=C+DD+E+F-1524 SET /A DOW=(JDN+1)%%7 

DOW es 0 para el domingo, 1 para el lunes, etc.

Pensé que mi primera respuesta da el día correcto de la semana como un número entre 0 y 6. Sin embargo, como no ha indicado por qué esta respuesta no arroja el resultado que desea, solo puedo adivinar el motivo.

El archivo por lotes a continuación crea un archivo de registro cada día con un dígito en el nombre, 0 = domingo, 1 = lunes, etc. … El progtwig asume que echo %date% muestra la fecha en formato MM / DD / AAAA; si este no es el caso, simplemente cambie la posición de las variables mm y dd en el comando for .

 @echo off for /F "tokens=1-3 delims=/" %%a in ("%date%") do set /A mm=10%%a %% 100, dd=10%%b %% 100, yy=%%c if %mm% lss 3 set /A mm+=12, yy-=1 set /A a=yy/100, b=a/4, c=2-a+b, e=36525*(yy+4716)/100, f=306*(mm+1)/10, dow=(c+dd+e+f-1523)%%7 echo Today log data > Day-%dow%.txt 

Si esto no es lo que quieres, indica el problema para que pueda solucionarlo.

EDITAR : la siguiente versión obtiene partes de fecha independientes de la configuración regional:

 @echo off for /F "skip=1 tokens=2-4 delims=(-/)" %%A in ('date ^< NUL') do ( for /F "tokens=1-3 delims=/" %%a in ("%date%") do ( set %%A=%%a set %%B=%%b set %%C=%%c ) ) set /A mm=10%mm% %% 100, dd=10%dd% %% 100 if %mm% lss 3 set /A mm+=12, yy-=1 set /A a=yy/100, b=a/4, c=2-a+b, e=36525*(yy+4716)/100, f=306*(mm+1)/10, dow=(c+dd+e+f-1523)%%7 echo Today log data > Day-%dow%.txt 

EDITAR : La siguiente versión inserta el día de la semana como un nombre corto de 3 letras:

 @echo off for /F "skip=1 tokens=2-4 delims=(-/)" %%A in ('date ^< NUL') do ( for /F "tokens=1-3 delims=/" %%a in ("%date%") do ( set %%A=%%a set %%B=%%b set %%C=%%c ) ) set /A mm=10%mm% %% 100, dd=10%dd% %% 100 if %mm% lss 3 set /A mm+=12, yy-=1 set /A a=yy/100, b=a/4, c=2-a+b, e=36525*(yy+4716)/100, f=306*(mm+1)/10, dow=(c+dd+e+f-1523)%%7 + 1 for /F "tokens=%dow%" %%a in ("Sun Mon Tue Wed Thu Fri Sat") do set dow=%%a echo Today log data > Day-%dow%.txt 

Saludos,

Antonio

Esto resultó ser mucho más complejo de lo que sospeché por primera vez, y supongo que eso es lo que me intrigó, busqué en todas partes y todos los métodos dados no funcionarían en Windows 7.

Así que tengo una solución alternativa que utiliza una secuencia de comandos de Visual Basic.

El lote crea y ejecuta el script (DayOfWeek.vbs), asigna el resultado de scripts (lunes, martes, etc.) a una variable (dow), luego se verifica la variable y se asigna otra variable (dpwnum) con el número de días, luego el VBS se borra espero que ayude:

 @echo off REM Create VBS that will get day of week in same directory as batch echo wscript.echo WeekdayName(Weekday(Date))>>DayOfWeek.vbs REM Cycle through output to get day of week ie monday,tuesday etc for /f "delims=" %%a in ('cscript /nologo DayOfWeek.vbs') do @set dow=%%a REM delete vbs del DayOfWeek.vbs REM Used for testing outputs days name echo %dow% REM Case of the days name is important must have a capital letter at start REM Check days name and assign value depending IF %dow%==Monday set downum=0 IF %dow%==Tuesday set downum=1 IF %dow%==Wednesday set downum=2 IF %dow%==Thursday set downum=3 IF %dow%==Friday set downum=4 IF %dow%==Saturday set downum=5 IF %dow%==Sunday set downum=6 REM print the days number 0-mon,1-tue ... 6-sun echo %downum% REM set a file name using day of week number set myfile=%downum%.bak echo %myfile% pause exit 

EDITAR:

Aunque recurrí a VBS, se puede hacer en lote puro, me tomó un tiempo ponerlo en funcionamiento y buscar mucho jajaja, pero parece que funciona:

  @echo off SETLOCAL enabledelayedexpansion SET /a count=0 FOR /F "skip=1" %%D IN ('wmic path win32_localtime get dayofweek') DO ( if "!count!" GTR "0" GOTO next set dow=%%D SET /a count+=1 ) :next echo %dow% pause 

La única advertencia para usted en el lote anterior es que su día de semanas es de 1-7 y no de 0-6

Esto funciona para mí

 FOR /F "tokens=3" %%a in ('robocopy ^|find "Started"') DO SET TODAY=%%a 

Este no es mi trabajo (bueno, lo modifiqué ligeramente del ejemplo), y es tarde para el juego, pero esto funciona en Server 2003 para mí;

 @echo off set daysofweek=Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday for /F "skip=2 tokens=2-4 delims=," %%A in ('WMIC Path Win32_LocalTime Get DayOfWeek /Format:csv') do set daynumber=%%A for /F "tokens=%daynumber% delims=," %%B in ("%daysofweek%") do set day=%%B 

Cita: TechSupportForum

Primero, copie CON SETUPDAY.001 SET WORKDAY = ^ Z (muy importante, sin cr / lf)

 DATE /T >SETUPDAY.002 COPY SETUPDAY.001+SETUPDAY.002 NEWDAY.BAT >nul CALL NEWDAY.BAT SET WEEKDAY=%WORKDAY:~0,3% SET MDY=%WORKDAY:~4,10% 

USE% WEEKDAY% EN SU GUIÓN

Versión dependiente de la configuración regional: en algunos entornos, lo siguiente extraerá el nombre del día de la fecha:

 set dayname=%date:~0,3% 

Supone que el nombre del día es la primera parte de %date% . Dependiendo de la configuración de la máquina, sin embargo, la parte de la subcadena ( ~0,3 ) tendría que cambiar.

Una afirmación como esta arrojaría a un archivo con un nombre de día de tres caracteres:

 set logfile=%date:~0,3%.log echo some stuff > %logfile% 

Versión independiente de la configuración regional: si la necesita menos dependiendo del formato del día actual de la máquina, otra forma de hacerlo sería escribir una pequeña aplicación que imprima el día de la semana. Luego use la salida de ese progtwig del archivo por lotes. Por ejemplo, la siguiente aplicación C imprime dayN donde N = 0..6.

 #include  #include  

Si lo anterior se compiló y se vinculó como myday.exe , entonces podría usarlo desde un archivo por lotes como este:

 for /f %%d in ('myday.exe') do set logfile=%%d.log echo some stuff > %logfile% 

Estoy en los Estados Unidos. Puedo ejecutar este código en Windows 7, Windows 2008 R2, Windows Server 2003, Windows XP (todos los SO están actualizados con las actualizaciones y parches de Windows). Todo con una configuración de fecha corta sin ddd (o dddd) (día de la semana).

 @echo off for /f %%a in ('date /t') do set DAY=%%a echo. echo The Day Is: %DAY% echo. 

Si hoy es jueves, saldrá “The Day Is: Thu”.

Esto devuelve el día en las 4 versiones de Windows en las que he probado. Y solo el día. Cuando cambié mi configuración de fecha corta para que fuera “ddd, M / d / aaaa”, mi salida mostraba el día con una coma (por ejemplo, Thu,) que me dice que este código usa el formato de fecha corta. Pero lo que también puede estar sucediendo es que si la fecha corta no contiene el día de la semana, puede parecerse al formato de fecha larga que en las 4 máquinas en las que probé, se ha dddd en el formato.

Tengo esta solución funcionando para mí:

Crea un archivo llamado dayOfWeek.vbs en el mismo directorio donde irá el archivo cmd.

dayOfWeek.vbs contiene una sola línea:

 wscript.stdout.write weekdayname(weekday(date)) 

o, si desea el número del día en lugar del nombre:

 wscript.stdout.write weekday(date) 

El archivo cmd tendrá esta línea:

 For /F %%A In ('CScript dayOfWeek.vbs //NoLogo') Do Set dayName=%%A 

Ahora puede usar la variable dayName como:

 robocopy c:\inetpub \\DCStorage1\Share1\WebServer\InetPub_%dayName% /S /XD history logs 

Si puede cambiar el formato de la fecha corta en la PC a “ddd aaaa-MM-dd” (solo el primer parámetro ‘ddd’ es obligatorio), el siguiente comando devuelve-

 c:\>vol | date The current date is: Mon 2014-12-01 

Entonces puedes escribir tu archivo por lotes –

 @echo off vol | date | find /i "sun" > nul if not errorlevel 1 goto SUN vol | date | find /i "mon" > nul if not errorlevel 1 goto MON # write block for other week days goto END :SUN set fname="sun" goto BACKUP :MON set fname="mon" goto BACKUP # write block for other week days :BACKUP echo %fname% :END 
 Rem Remove the end comma and add /A to set for this line worked for me. set /A a=yy/100, b=a/4, c=2-a+b, e=36525*(yy+4716)/100, f=306*(mm+1)/10 

Quería hacer esto yo mismo y vi quejas sobre líneas en blanco:

 rem Make the win32_localtime output all one line, though some versions may contain blank lines as well. rem So ignore blank lines and just pick up the number after the equal sign. for /f "delims== tokens=2" %%a in ('wmic path win32_localtime get dayofweek /format:list') do ( rem Increment the DOW as it is documented to be a zero-based index starting with Sunday. set /a DayOfWeekIndex=%%a+1 ) rem Also get name day of week. The DOW coming in is now a one-based index. rem This is used to reference the "array" of week day names. set DayOfWeekNames=Sun Mon Tue Wed Thu Fri Sat for /f "tokens=%DayOfWeekIndex%" %%b in ("%DayOfWeekNames%") do ( set DayOfWeekName=%%b ) 

Mejore la respuesta de Aacini para hacerla eco Día completo de la semana Nombre

Así que aquí está mi Código

 @echo off for /F "skip=1 tokens=2-4 delims=(-/)" %%A in ('date ^< NUL') do ( for /F "tokens=1-3 delims=/" %%a in ("%date%") do ( set %%A=%%a set %%B=%%b set %%C=%%c ) ) set /A mm=10%mm% %% 100, dd=10%dd% %% 100 if %mm% lss 3 set /A mm+=12, yy-=1 set /A a=yy/100, b=a/4, c=4-a+b, e=36525*(yy+4716)/100, f=306*(mm+1)/10,dow=(c+dd+e+f-1523)%%7 + 1 for /F "tokens=%dow%" %%a in ("Sunday Monday Tuesday Wednesday Thursday Friday Saturday ") do set dow=%%a echo Today is %dow%>"Today is %dow%.txt" echo Today is %dow% Pause>Nul REM Sun Mon Tue Wed Thu Fri Sat REM Sunday Monday Tuesday Wednesday Thursday Friday Saturday 

Una versión que usa MSHTA y javascript. Cambie% jsfunc% a la función jScript que desea llamar

 @echo off ::Invoke a javascript function using mhta set jsfunc=new Date().getDay() set dialog="about:" for /f "tokens=* delims=" %%p in ('mshta.exe %dialog%') do set ndow=%%p ::get dow string from array of strings for /f "tokens=%ndow%" %%d in ("Mon Tue Wed Thu Fri Sat Sun") do set dow=%%d echo dow is : %ndow% %dow% pause