毎日実行されるWindowsバッチファイルがあります。データをファイルに記録し、それをローテーションしたい(つまり、最大で過去7日間分のデータがある)。
コマンドDATE
を調べて、 DELIMS
-解決策を見つけられません。
曜日を含むファイル名を作成する簡単な解決策はありますか?つまり、月曜日の場合は0などです。
または、より良いシェルスクリプトに頼る必要がありますか?
毎日実行されるWindowsバッチファイルがあります。データをファイルに記録し、それをローテーションしたい(つまり、最大で過去7日間分のデータがある)。
コマンドDATE
を調べて、 DELIMS
-解決策を見つけられません。
曜日を含むファイル名を作成する簡単な解決策はありますか?つまり、月曜日の場合は0などです。
または、より良いシェルスクリプトに頼る必要がありますか?
%DATE%
あなたの友達ではありません。%DATE%
環境変数 (およびコマンド) は、完全かつ無限にカスタマイズ可能なWindows の短い日付形式DATE
を使用して現在の日付を返すためです。あるユーザーは 07/06/2012 を返すようにシステムを構成し、別のユーザーは Fri060712 を選択する場合があります。を使用することは、BAT プログラマーにとって完全な悪夢です。%DATE%
この問題を解決するには、次の 2 つの方法があります。
レジストリ値のロケール設定を変更して、短い日付形式を一時的にHKCU\Control Panel\International\sShortDate
認識可能な形式に変更したくなるかもしれません。次に%DATE%
、必要な形式で日付を取得するためにアクセスします。最後に、フォーマットを元のユーザー フォーマットに戻します。このようなもの
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
しかし、この方法には 2 つの問題があります。
ローカルの特定の目的のためにグローバル レジストリ値を改ざんするため、同時に実行された場合はそれ自体を含め、短い日付形式で日付を同時にクエリする他のプロセスまたはユーザー タスクを妨害する可能性があります。
また、3 文字の曜日をローカル言語で返しますが、これはシステムやユーザーによって異なる場合があります。
WMIC Win32_LocalTimeを使用します。これは、便利な方法で日付を返し、FOR
コマンドで直接解析します。
FOR /F "skip=1" %%A IN ('WMIC Path Win32_LocalTime Get DayOfWeek' ) DO (
set DOW=%%A
)
これは私が推奨する方法です。
@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 は、日曜日は 0、月曜日は 1 などです。
私の最初の回答は正しい曜日を 0 から 6 までの数字で示していると思いました。
以下のバッチ ファイルは、名前に 0 = 日曜日、1 = 月曜日などの数字を含むログ ファイルを毎日作成します。プログラムはecho %date%
、MM/DD/YYYY 形式で日付を表示すると想定しています。そうでない場合は、for
コマンド内の mm および dd 変数の位置を変更するだけです。
@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
これがあなたの望むものでない場合は、私が修正できるように問題を指摘してください。
編集: 以下のバージョンは、ロケール設定とは無関係に日付部分を取得します。
@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
編集: 以下のバージョンは、曜日を 3 文字の短い名前として挿入します。
@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
よろしく、
アントニオ
これは、私が最初に疑ったよりもはるかに複雑であることが判明しました。それが私を興味をそそったものだと思います。私はあらゆる場所を検索しましたが、指定されたすべての方法は Windows 7 では機能しませんでした。
そのため、Visual Basic Script を使用する代替ソリューションがあります。
バッチはスクリプト (DayOfWeek.vbs) を作成して実行し、スクリプトの出力 (月曜日、火曜日など) を変数 (dow) に割り当てます。変数がチェックされ、別の変数 (dpwnum) に日数が割り当てられ、その後 VBSそれが役立つことを願って削除されます:
@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
編集:
私はVBSに目を向けましたが、純粋なバッチで実行できます。機能させるのに時間がかかり、多くの検索が必要でしたが、これはうまくいくようです:
@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
上記のバッチに関する唯一の注意点は、曜日が 0 ~ 6 ではなく 1 ~ 7 であることです。
これは私のために働く
FOR /F "tokens=3" %%a in ('robocopy ^|find "Started"') DO SET TODAY=%%a
私は米国にいます。このコードは、Windows 7、Windows 2008 R2、Windows Server 2003、Windows XP で実行できます (すべての OS は Windows Update とパッチで最新です)。ddd (または dddd) (曜日) のない短い日付設定のすべて。
@echo off
for /f %%a in ('date /t') do set DAY=%%a
echo.
echo The Day Is: %DAY%
echo.
今日が木曜日の場合、「The Day Is: Thu」と出力されます。
これは、私がテストした 4 つの Windows バージョンすべてで日付を返します。しかも当日のみ。短い日付の設定を "ddd, M/d/yyyy" に変更すると、出力にコンマ (Thu など) を含む日が表示され、このコードが短い日付形式を使用していることがわかります。しかし、短い日付に曜日が含まれていない場合、テストした4台のマシンすべてでdddd形式の長い日付形式に見える可能性があります。
ロケール依存バージョン: 一部の環境では、次のように日付から曜日名が抽出されます。
set dayname=%date:~0,3%
曜日名がの最初の部分であると想定してい%date%
ます。ただし、マシンの設定によっては、部分文字列の部分(~0,3
)を変更する必要があります。
このようなステートメントは、3文字の日の名前を持つファイルにダンプします。
set logfile=%date:~0,3%.log
echo some stuff > %logfile%
ロケールに依存しないバージョン:現在のマシンの曜日の形式にあまり依存しないようにする必要がある場合、別の方法は、曜日を印刷する小さなアプリケーションを作成することです。次に、バッチファイルからのそのプログラムの出力を使用します。たとえば、次のCアプリケーションはdayN
、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 );
}
上記がコンパイルされmyday.exe
、としてリンクされている場合は、次のようなバッチファイルから使用できます。
for /f %%d in ('myday.exe') do set logfile=%%d.log
echo some stuff > %logfile%
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
MSHTA と javascript を使用したバージョン。%jsfunc% を、呼び出したい jscript 関数に変更します
@echo off
::Invoke a javascript function using mhta
set jsfunc=new Date().getDay()
set dialog="about:<script>resizeTo(0,0);new ActiveXObject('Scripting.FileSystemObject').
set dialog=%dialog%GetStandardStream(1).WriteLine(%jsfunc%);close();</script>"
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