J'ai un fichier batch Windows qui s'exécute quotidiennement. Souhaitez enregistrer des données dans un fichier et les faire pivoter (c’est-à-dire qu’elles ont au plus les 7 derniers jours de données).
A examiné les commandes DATE
et DELIMS
- Impossible de trouver une solution.
Existe-t-il une solution simple pour créer un nom de fichier contenant le jour de la semaine, à savoir 0 pour lundi, etc.
Ou dois-je avoir recours à un meilleur script Shell?.
%DATE%
n'est pas votre ami. Parce que la variable d'environnement %DATE%
(et la commande DATE
) renvoie la date actuelle à l'aide du format de date Windows short entièrement personnalisable à l'infini. Un utilisateur peut configurer le système pour renvoyer le 07/06/2012, tandis qu'un autre peut choisir Fri060712. Utiliser %DATE%
est un cauchemar complet pour un programmeur BAT.
Il existe deux approches possibles pour résoudre ce problème:
Vous pouvez être tenté de modifier temporairement le format de date courte en modifiant les paramètres régionaux de la valeur de registre HKCU\Control Panel\International\sShortDate
en un format reconnaissable. Ensuite, accédez à %DATE%
pour obtenir la date au format souhaité; et finalement restaurer le format au format utilisateur d'origine. Quelque chose comme ça
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
mais cette méthode a deux problèmes:
il altère une valeur de registre globale pour ses utilisateurs particuliers locaux, de sorte qu'il peut interférer avec d'autres processus ou tâches utilisateur qui interrogent en même temps la date au format de date court, y compris lui-même si elle est exécutée simultanément.
et il renvoie le jour de la semaine à trois lettres dans la langue locale qui peut être différente selon les systèmes ou les utilisateurs.
utilisez WMIC Win32_LocalTime , qui renvoie la date de manière pratique pour l’analyser directement avec une commande FOR
.
FOR /F "skip=1" %%A IN ('WMIC Path Win32_LocalTime Get DayOfWeek' ) DO (
set DOW=%%A
)
c'est la méthode que je recommande.
quelques autres moyens:
1 .Robocopy n'est pas disponible dans XP, mais peut être téléchargé sous la forme téléchargée à l'aide de la boîte à outils Windows 2003.
@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 - fonctionne sur toutes les machines Windows (mais crée un petit fichier temporaire) . Fonction fournie par 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 - utilise les commutateurs de commande introduits dans Vista, donc ne fonctionnera pas sous 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 (doit être enregistré au format .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(doit être enregistré au format .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 peuvent être téléchargés à partir de Microsoft. Disponible par défaut dans tout sous 7 et supérieur:
@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 déjà utilisé comme réponse, mais je veux juste avoir une référence complète. Et avec <CR>
effacé:
@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 (doit être enregistré sous le nom .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 /A A=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 est 0 pour le dimanche, 1 pour le lundi, etc.
Je pensais que ma première réponse donnait le bon jour de la semaine sous la forme d’un nombre compris entre 0 et 6. Cependant, comme vous aviez non indiqué pourquoi cette réponse ne donne pas le résultat souhaité, je ne peux que deviner la raison.
Le fichier batch ci-dessous crée un fichier journal chaque jour avec un chiffre dans le nom, 0 = dimanche, 1 = lundi, etc. Le programme suppose que echo %date%
affiche la date au format MM/JJ/AAAA; Si ce n'est pas le cas, changez simplement la position des variables mm et dd dans la commande 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 ce n'est pas ce que vous voulez, veuillez indiquer le problème pour que je puisse le résoudre.
EDIT: La version ci-dessous récupère les parties de date indépendamment des paramètres régionaux:
@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 version ci-dessous insère le jour de la semaine sous forme de nom abrégé de 3 lettres:
@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
Cordialement,
Antonio
Premier - Copier CON SETUPDAY.001 SET WORKDAY = ^ Z (très important - pas de 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%
UTILISER% WEEKDAY% DANS VOTRE SCRIPT
Ce n'est pas mon travail (enfin, je l'ai légèrement modifié à partir de l'exemple), et le jeu est en retard, mais cela fonctionne pour Server 2003 pour moi;
@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
Ça marche pour moi
FOR /F "tokens=3" %%a in ('robocopy ^|find "Started"') DO SET TODAY=%%a
Cela s'est avéré bien plus complexe que ce que je soupçonnais pour la première fois, et je suppose que c'est ce qui m'intriguait: j'ai cherché partout et toutes les méthodes données ne fonctionneraient pas sous Windows 7.
J'ai donc une solution alternative qui utilise un script Visual Basic.
Le lot crée et exécute le script (DayOfWeek.vbs), attribue les scripts de sortie (lundi, mardi, etc.) à une variable (dow), la variable est ensuite vérifiée et une autre variable (dpwnum) est affectée avec le nombre de jours, puis le VBS est supprimé espérons que cela aide:
@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 i.e 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
MODIFIER:
Bien que je me suis tourné vers VBS, cela peut être fait en batch, cela m’a pris un certain temps pour le faire fonctionner et beaucoup de recherches lol, mais cela semble fonctionner:
@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
Le seul inconvénient pour vous sur le lot ci-dessus est que son jour de semaines est compris entre 1 et 7 et non entre 0 et 6.
J'ai cette solution qui fonctionne pour moi:
Créez un fichier nommé dayOfWeek.vbs dans le même répertoire que le fichier cmd.
dayOfWeek.vbs contient une seule ligne:
wscript.stdout.write weekdayname(weekday(date))
ou, si vous voulez le numéro du jour au lieu du nom:
wscript.stdout.write weekday(date)
Le fichier cmd aura cette ligne:
For /F %%A In ('CScript dayOfWeek.vbs //NoLogo') Do Set dayName=%%A
Vous pouvez maintenant utiliser la variable dayName like:
robocopy c:\inetpub \\DCStorage1\Share1\WebServer\InetPub_%dayName% /S /XD history logs
Je suis aux USA. Je peux exécuter ce code sous Windows 7, Windows 2008 R2, Windows Server 2003, Windows XP (tous les systèmes d'exploitation sont à jour avec les mises à jour et les correctifs Windows). Tous avec réglage de la date courte sans ddd (ou dddd) (jour de la semaine).
@echo off
for /f %%a in ('date /t') do set DAY=%%a
echo.
echo The Day Is: %DAY%
echo.
Si nous sommes aujourd'hui jeudi, le résultat sera "The Day Is: Thu".
Ceci renvoie la journée sur les 4 versions de Windows sur lesquelles j'ai testé. Et seulement le jour. Lorsque j'ai modifié ma configuration de date courte en "jj/j/j/aaaa", ma sortie indiquait le jour avec une virgule (par exemple, Thu,) qui indique que ce code utilise le format de date courte. Mais il se peut aussi que si la date courte ne contienne pas le jour de la semaine, le format de la date longue peut être utilisé, car sur les 4 machines sur lesquelles j'ai testé, le format est dddd.
Version dépendante des paramètres régionaux: Dans certains environnements, les éléments suivants extrairont le nom du jour à partir de la date:
set dayname=%date:~0,3%
Cela suppose que le nom du jour est la première partie de %date%
. Cependant, en fonction des paramètres de la machine, la partie sous-chaîne (~0,3
) devra être modifiée.
Une instruction telle que celle-ci serait transférée dans un fichier avec un nom de jour à trois caractères:
set logfile=%date:~0,3%.log
echo some stuff > %logfile%
Version indépendante de la localisation: Si vous en avez besoin moins dépendant du format de jour de la machine actuelle, vous pouvez également écrire une petite application qui imprime le jour de la semaine. Ensuite, utilisez la sortie de ce programme à partir du fichier de commandes. Par exemple, l'application C suivante imprime dayN
où N = 0..6.
#include <stdio.h>
#include <time.h>
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 );
}
Si les éléments ci-dessus ont été compilés et liés en tant que myday.exe
, vous pouvez les utiliser à partir d'un fichier de commandes comme celui-ci:
for /f %%d in ('myday.exe') do set logfile=%%d.log
echo some stuff > %logfile%
Si vous pouvez changer le format de date courte dans le PC en "jj aaaa-MM-jj" (seul le premier paramètre "jjd" est obligatoire), la commande suivante renvoie
c:\>vol | date
The current date is: Mon 2014-12-01
Ensuite, vous pouvez écrire votre fichier de commandes -
@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
Je cherchais à le faire moi-même et j'ai vu des plaintes concernant des lignes vierges:
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
)
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
Un autre tour sur ce sujet. Le script ci-dessous affiche quelques jours près du jour actuel, avec le préfixe du jour de la semaine.
La routine autonome: dpack, qui code la date en une valeur dont modulo 7 révèle le jour de la semaine selon les normes ISO 8601 (lundi == 0), constitue l’essentiel. Est également fourni: dunpk qui est la fonction inverse:
@echo off& setlocal enabledelayedexpansion
rem 10/23/2018 daydate.bat: Most recent version at paulhoule.com/daydate
rem Example of date manipulation within a .BAT file.
rem This is accomplished by first packing the date into a single number.
rem This demo .bat displays dates surrounding the current date, prefixed
rem with the day-of-week.
set days=0Mon1Tue2Wed3Thu4Fri5Sat6Sun
call :dgetl y m d
call :dpack p %y% %m% %d%
for /l %%o in (-3,1,3) do (
set /a od=p+%%o
call :dunpk y m d !od!
set /a dow=od%%7
for %%d in (!dow!) do set day=!days:*%%d=!& set day=!day:~,3!
echo !day! !y! !m! !d!
)
exit /b
rem gets local date returning year month day as separate variables
rem in: %1 %2 %3=var names for returned year month day
:dgetl
setlocal& set "z="
for /f "skip=1" %%a in ('wmic os get localdatetime') do set z=!z!%%a
set /a y=%z:~0,4%, m=1%z:~4,2% %%100, d=1%z:~6,2% %%100
endlocal& set /a %1=%y%, %2=%m%, %3=%d%& exit /b
rem packs date (y,m,d) into count of days since 1/1/1 (0..n)
rem in: %1=return var name, %2= y (1..n), %3=m (1..12), %4=d (1..31)
rem out: set %1= days since 1/1/1 (modulo 7 is weekday, Mon= 0)
:dpack
setlocal enabledelayedexpansion
set mtb=xxx 0 31 59 90120151181212243273304334& set /a r=%3*3
set /a t=%2-(12-%3)/10, r=365*(%2-1)+%4+!mtb:~%r%,3!+t/4-(t/100-t/400)-1
endlocal& set %1=%r%& exit /b
rem inverse of date packer
rem in: %1 %2 %3=var names for returned year month day
rem %4= packed date (large decimal number, eg 736989)
:dunpk
setlocal& set /a y=%4+366, y+=y/146097*3+(y%%146097-60)/36524
set /a y+=y/1461*3+(y%%1461-60)/365, d=y%%366+1, y/=366
set e=31 60 91 121 152 182 213 244 274 305 335
set m=1& for %%x in (%e%) do if %d% gtr %%x set /a m+=1, d=%d%-%%x
endlocal& set /a %1=%y%, %2=%m%, %3=%d%& exit /b
J'ai amélioré Aacini Réponse Pour le rendre en écho Journée complète de la semaine
Alors voici mon code
@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