21

毎日実行されるWindowsバッチファイルがあります。データをファイルに記録し、それをローテーションしたい(つまり、最大で過去7日間分のデータがある)。

コマンドDATEを調べて、 DELIMS-解決策を見つけられません。

曜日を含むファイル名を作成する簡単な解決策はありますか?つまり、月曜日の場合は0などです。

または、より良いシェルスクリプトに頼る必要がありますか?

4

17 に答える 17

32

%DATE%あなたの友達ではありません。%DATE%環境変数 (およびコマンド) は、完全かつ無限にカスタマイズ可能なWindows の短い日付形式DATEを使用して現在の日付を返すためです。あるユーザーは 07/06/2012 を返すようにシステムを構成し、別のユーザーは Fri060712 を選択する場合があります。を使用することは、BAT プログラマーにとって完全な悪夢です。%DATE%

この問題を解決するには、次の 2 つの方法があります。

  1. レジストリ値のロケール設定を変更して、短い日付形式を一時的に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 文字の曜日をローカル言語で返しますが、これはシステムやユーザーによって異なる場合があります。

  2. WMIC Win32_LocalTimeを使用します。これは、便利な方法で日付を返し、FORコマンドで直接解析します。

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

    これは私が推奨する方法です。

于 2012-07-06T18:19:02.830 に答える
6
@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 などです。

于 2012-07-07T01:34:29.347 に答える
4

私の最初の回答は正しい曜日を 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

よろしく、

アントニオ

于 2012-07-15T16:21:45.107 に答える
3

これは、私が最初に疑ったよりもはるかに複雑であることが判明しました。それが私を興味をそそったものだと思います。私はあらゆる場所を検索しましたが、指定されたすべての方法は Windows 7 では機能しませんでした。

そのため、Visual Basic Sc​​ript を使用する代替ソリューションがあります。

バッチはスクリプト (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 であることです。

于 2012-07-20T21:42:23.690 に答える
3

これは私のために働く

FOR /F "tokens=3" %%a in ('robocopy ^|find "Started"') DO SET TODAY=%%a
于 2014-03-06T04:36:56.653 に答える
2

私は米国にいます。このコードは、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形式の長い日付形式に見える可能性があります。

于 2014-02-06T18:32:14.763 に答える
1

ロケール依存バージョン: 一部の環境では、次のように日付から曜日名が抽出されます。

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%
于 2012-07-06T14:38:42.813 に答える
0
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 
于 2013-12-01T21:09:39.850 に答える
-1

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
于 2016-05-09T22:10:05.997 に答える