Impostazione di una variabile del file batch di Windows sul giorno della settimana

Ho un file batch di Windows che viene eseguito ogni giorno. Desidera registrare i dati in un file e volerlo ruotare (ovvero avere al massimo gli ultimi 7 giorni di dati).

Guardato nei comandi DATE e DELIMS – Imansible capire una soluzione.

C’è una soluzione semplice per creare un nome di file che contiene il giorno della settimana, ad esempio 0 per il lunedì ecc.

O devo ricorrere a qualche script di shell migliore.

%DATE% non è tuo amico. Poiché la variabile di ambiente %DATE% (e il comando DATE ) restituisce la data corrente utilizzando il formato di data breve di Windows completamente e infinitamente personalizzabile. Un utente può configurare il sistema per restituire 07/06/2012 mentre un altro potrebbe scegliere Fri060712. L’utilizzo di %DATE% è un incubo completo per un programmatore BAT.

Esistono due possibili approcci per risolvere questo problema:

  1. Potresti essere tentato di modificare temporaneamente il formato della data breve, modificando le impostazioni locali nel valore di registro HKCU\Control Panel\International\sShortDate , nel formato riconoscibile. Quindi accedi a %DATE% per ottenere la data nel formato desiderato; e infine ripristinare il formato nel formato utente originale. Qualcosa come questo

     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 

    ma questo metodo ha due problemi:

    • altera il valore di un registro globale per i suoi specifici scopi locali, quindi può interferire con altri processi o attività dell’utente che allo stesso tempo interrogano la data in formato data breve, incluso se stessa se eseguita simultaneamente.

    • e restituisce le tre lettere della settimana nella lingua locale che potrebbero essere diverse in sistemi diversi o utenti diversi.

  2. utilizzare WMIC Win32_LocalTime , che restituisce la data in un modo conveniente per analizzarlo direttamente con un comando FOR .

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

    questo è il metodo che raccomando.

pochi altri modi:

1. Robocopy non è disponibile in XP, ma può essere scaricato in forma con il toolkit delle risorse di win 2003.Inoltre può dipendere dalla localizzazione:

 @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 : funziona su ogni macchina Windows (ma crea un piccolo file temporaneo). Funzione fornita da 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 – utilizza le opzioni di comando introdotte in Vista quindi non funzionerà su 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. .bat / jscript hybrid (deve essere salvato come .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. .bat / vbscript hybrid (deve essere salvato come .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 può essere scaricato da microsoft.Available di default in tutto il modulo win7 e sopra:

 @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 è già utilizzato come risposta ma desidera solo avere un riferimento completo. E con clear :

 @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. Jscript.net auto compilato (deve essere salvato come .bat ):

 @if (@X)==(@Y) @end /****** silent line that start jscript comment ****** @echo off :::::::::::::::::::::::::::::::::::: ::: compile the script :::: :::::::::::::::::::::::::::::::::::: setlocal if exist "%~n0.exe" goto :skip_compilation 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 compilation :::: :::::::::::::::::::::::::::::::::::: :skip_compilation "%~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 è 0 per domenica, 1 per lunedì, ecc.

Ho pensato che la mia prima risposta fornisse il giorno della settimana corretto come un numero compreso tra 0 e 6. Tuttavia, poiché non avevi indicato perché questa risposta non dà il risultato desiderato, posso solo indovinarne il motivo.

Il file Batch sottostante crea un file di registro ogni giorno con una cifra nel nome, 0 = domenica, 1 = lunedì, ecc … Il programma presuppone che echo %date% mostri la data nel formato MM / GG / AAAA; se questo non è il caso, basta cambiare la posizione delle variabili mm e dd nel 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 

Se questo non è ciò che desideri, ti preghiamo di indicare il problema in modo da poterlo risolvere.

EDIT : la versione seguente ottiene le parti della data indipendentemente dalle impostazioni locali:

 @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 

EDIT : la versione di seguito inserisce giorno della settimana come nome breve di 3 lettere:

 @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 

Saluti,

Antonio

Questo risultò molto più complesso di quanto sospettassi inizialmente, e suppongo sia questo che mi ha incuriosito, ho cercato ogni dove e tutti i metodi dati non avrebbero funzionato su Windows 7.

Quindi ho una soluzione alternativa che utilizza uno script di Visual Basic.

Il batch crea ed esegue lo script (DayOfWeek.vbs), assegna l’output degli script (lunedì, martedì ecc.) A una variabile (dow), la variabile viene quindi controllata e un’altra variabile (dpwnum) assegnata con il numero dei giorni, in seguito il VBS è cancellato spero che aiuti:

 @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 

MODIFICARE:

Anche se mi sono rivolto a VBS, può essere fatto in puro batch, mi ci è voluto un po ‘per farlo funzionare e un sacco di ricerche lol, ma questo sembra funzionare:

  @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 

L’unico avvertimento per il gruppo sopra riportato è che il suo giorno di settimane è 1-7 e non 0-6

Questo funziona per me

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

Questo non è il mio lavoro (beh, l’ho leggermente modificato dall’esempio), ed è tardi per il gioco, ma questo funziona su Server 2003 per me;

 @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 

Citation: TechSupportForum

Primo: Copia CON SETUPDAY.001 SET WORKDAY = ^ Z (molto importante – no 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% NEL TUO SCRIPT

Versione dipendente dalla locale: in alcuni ambienti, il seguente nome estrarrà il nome del giorno dalla data:

 set dayname=%date:~0,3% 

Si presuppone che il nome del giorno sia la prima parte di %date% . A seconda delle impostazioni della macchina, tuttavia, è necessario modificare la parte della sottostringa ( ~0,3 ).

Un’affermazione come questa eseguirà il dump su un file con un nome di giorno di tre caratteri:

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

Versione indipendente dalla locale: se ne hai bisogno meno dipendente dal formato del giorno corrente della macchina, un altro modo di farlo sarebbe scrivere una piccola applicazione che stampa il giorno della settimana. Quindi utilizzare l’output di quel programma dal file batch. Ad esempio, la seguente applicazione C stampa dayN dove N = 0..6.

 #include  #include  int main( int argc, char* argv[] ) { time_t curtime; struct tm * tmval; time( &curtime ); tmval = localtime( &curtime ); // print dayN. Or use a switch statement and print // the actual day name if you want printf( "day%d", tmval->tm_wday ); } 

Se quanto sopra è stato compilato e collegato come myday.exe , puoi usarlo da un file batch come questo:

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

Sono negli Stati Uniti. Posso eseguire questo codice in Windows 7, Windows 2008 R2, Windows Server 2003, Windows XP (tutti i sistemi operativi sono aggiornati con aggiornamenti e patch di Windows). Tutto con impostazione data breve senza ddd (o dddd) (giorno della settimana).

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

Se oggi è giovedì, uscirà “The Day Is: Thu”.

Ciò restituisce il giorno in tutte e 4 le versioni di Windows su cui ho eseguito il test. E solo il giorno. Quando ho modificato la mia impostazione di data breve in “ddd, M / g / aaaa”, il mio output mostrava il giorno con una virgola (ad es. Thu,) che mi dice che questo codice usa il formato di data breve. Ma quello che potrebbe anche accadere è che se la data breve non contiene il giorno della settimana, potrebbe sembrare il formato a lunga data che su tutte e 4 le macchine su cui ho provato, ha il formato dddd.

Ho questa soluzione che funziona per me:

Creare un file denominato dayOfWeek.vbs nella stessa dir dove andrà il file cmd.

dayOfWeek.vbs contiene una singola riga:

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

oppure, se desideri il numero del giorno invece del nome:

 wscript.stdout.write weekday(date) 

Il file cmd avrà questa linea:

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

Ora puoi usare variabile dayName come:

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

Se è ansible modificare il formato della data breve nel PC su “gg / aaaa-MM-gg” (solo il primo parametro ‘ddd’ è obbligatorio), quindi il comando restituisce-

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

Quindi puoi scrivere il tuo file batch –

 @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 

Stavo cercando di farlo da solo e ho visto lamentele sulle righe vuote:

 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 ) 

I Migliorato Aacini Risposta per renderlo eco Nome completo giorno della settimana

Quindi, ecco il mio codice

 @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 versione che utilizza MSHTA e javascript. Cambia% jsfunc% per utilizzare la funzione jscript che vuoi chiamare

 @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