スラッシュドット    はてなブックマーク  Yahoo!ブックマークに登録  印刷
Windows TIPS
[Scripting]
  Windows TIPS TOPへ
Windows TIPS全リストへ
内容別分類一覧へ

バッチ・ファイル中で日付をファイル名に使用する

解説をスキップして操作方法を読む

デジタルアドバンテージ
2004/05/01
2004/05/05更新
2007/10/12更新
対象OS
Windows 2000
Windows XP
Windows Server 2003
Windows Vista
バッチ・ファイル中で日付や時間をベースにしたファイル名を利用したい場合がある。
このような用途では、環境変数の%date%や%time%を利用して、ファイル名を合成すればよい。
 
解説

 バッチ・ファイル中で、日付や時間をベースにしたファイル名を利用したい場合は少なくない。例えばシステム・データやユーザー・ファイルをまとめてバックアップし、バックアップ先のフォルダやファイル名に、その日の日付を反映した名前(例:「systemconfig-20040501」や「user1-040501」など)を付けたいといった場合である。

 このような目的のためには、環境変数の「date」や「time」を使えばよい。それぞれ、今日の日付と現在の時刻(を文字列にして)を返す関数である(以下はWindows XPおよびWindows Server 2003での実行例)。

C:\>echo %date%
2004/04/28

C:\>echo %time%
14:54:08.22

 だがこれらの変数の返す値には、「/」や「:」といった、ファイル名としては利用できない文字が含まれている。そこでファイル名を生成する場合にはこれらの文字を取り除き、数字の部分だけを使えばよい。

 ただしWindows 2000の場合は次のように、日付の直前に曜日を表す文字が表示されるので、これを取り除いて処理する必要がある(文字列の最後の10文字だけを取り出すようにすればよい)。

C:\>echo %date%
水 2004/04/28

  操作方法

環境変数から数値部分を抽出する

 dateやtime変数から、数字の部分だけを取り出すには、単に「%date%」「%time%」とするのではなく、変数値の部分文字列抽出用の修飾を行えばよい。ある変数Vの、先頭からm番目の文字からn文字分を取り出すには、「%V:~m,n%」とする(mは0から始まる)。例えば変数Vの値が「ABCDEFGHIJKL」の場合、6文字目から2文字分取り出すには「%V:~5,2%」とすればよい(先頭文字は0番目と数えるので、6ではなく5を指定する)。

C:\>set V=ABCDEFGHIJKL

C:\>echo %V:~5,2%
FG

 nを省略すると、位置mから最後までとなる(例:%V:~5%なら「FGHIJKL」となる)。mに負の数を指定すると、先頭ではなく、最後尾から数えた文字位置になる(%V:~-3%ならば最後の3文字「JKL」になる)。またnに負の数を指定すると、最後のn文字を除いた部分の文字列となる(位置mからn文字目の直前まで。例えば%V:~5,-3%ならばFGHIとなる)。まとめると、次のようになる。

書式 意味
%V% 変数Vの値全体 %V% ⇒「ABCDEFGHIJKL」
%V:~m% m文字目から、最後まで %V:~5% ⇒「FGHIJKL」
%V:~m,n% m文字目から、n文字分 %V:~5,2% ⇒「FG」
%V:~m,-n% m文字目から、最後のn文字分を除いたもの %V:~5,-2% ⇒「FGHIJ」
%V:~-m% 後ろからm文字目から、最後まで %V:~-5% ⇒「HIJKL」
%V:~-m,n% 後ろからm文字目から、n文字分 %V:~-5,2% ⇒「HI」
%V:~-m,-n% 後ろからm文字目から、最後のn文字分を除いたもの %V:~-5,-2% ⇒「HIJ」
%V:c1=c2% 文字c1を文字c2に置換する。それぞれ複数の文字を指定することも可能 %V:ABC=abc% ⇒「abcDEFGHIJKL」
変数の部分文字列の抽出と置換
変数の値全体を参照するには「%V%」とするが、変数名の修飾子として「:~<数字>」を付けることにより、文字列の一部分だけを取り出すことができる。ここではVの値は「ABCDEFGHIJKL」とする。修飾子の詳しい解説はコマンド・プロンプト上で「set /?」を実行すると表示される。

 この結果、%date%変数から数字の部分だけを抜き出すには、「%date:~0,4%%date:~5,2%%date:~8,2%」とすればよいことが分かるだろう(年と月と日の部分をそれぞれ抜き出して結合している)。

C:\>echo %date%
2004/04/30

C:\>echo %date:~0,4%%date:~5,2%%date:~8,2%
20040430

※これはWindows 2000では正しく動作しない

 ただしWindows 2000の場合は%date%の先頭に曜日が表示されるので、これを取り除くためには、%date%ではなく、%date:~-10%とする。これにより、%date%変数の値のうち、文字列の最後から10文字だけを取り出すことができる。この方法はWindows XPやWindows Server 2003でもそのまま利用できる。

C:\>echo %date:~-10,4%%date:~-5,2%%date:~-2,2%
20071012

※これはWindows 2000でも、それ以外のWindows OSでも正しく動作する

時刻の計算

 日付の場合と同様に、時刻(時分秒)の場合にも少し注意点がある。午前0時から午前10時(00:00:59〜9;59:59)の場合、%time%が返す文字列の先頭には、「0」ではなく、空白文字が含まれている(00、01、02……、09、10、11、……ではなく、0、1、2、……、9、10、11、……となる)。つまり時(0〜23)の数値はゼロサプレスされて表示されている。そのため、時間を取り出すために、単純に%time:~0,2%%time:~3,2%%time:~6,2%とすると、先頭に空白文字が入っている可能性がある。これをそのままファイル名やバッチ・ファイルのパラメータとして利用すると、空白文字によって引数の区切りとして扱われるなどの不具合が生じる可能性がある。

C:\>time 1:23

C:\>echo %time%
 1:23:04.29

C:\>time 12:34

C:\>echo %time%
12:34:01.60

 このような不具合を防ぐためには、%time%変数に含まれる空白文字を、最初に数字の0に置き換えておけばよいだろう。変数の置換は先の表にあるように、%V:c1=c2%とすればよい。ここでc1には空白文字を、c2には0を指定する。

C:\>echo %time:~0,2%%time:~3,2%%time:~6,2%
 11204   …置換しない場合は、このように先頭に空白文字が含まれる

C:\>set time2=%time: =0%   …いったん一時変数に入れて置換する

C:\>echo %time2:~0,2%%time2:~3,2%%time2:~6,2%
011204   …先頭に空白文字は含まれず、必ず数字が入る

 なお、一度変数time2に入れてから次の行で2桁ずつ取り出しているのは、文字列の置換と部分抽出を同時に行えないからである。

ntbackupコマンドでシステム状態をバックアップする

 この手法を利用して、例えばntbackup.exeコマンドで「システム状態(システムのレジストリやActive Directoryの状態などのデータ)」だけをバックアップするには次のようにする。出力先は、このバッチ・ファイルを起動したドライブの「\Backup」というフォルダであり、出力ファイルにはバックアップした日付を含めたファイル名を付ける。また、このファイルをどこか別のシステムへコピーして保存することを考え、ファイル名にはサーバ名も含めるようにしている。これにより、どのシステムでいつバックアップしたかがすぐに分かるようになる。

※ファイル:systembackupcmd.bat

REM BACKUP SYSTEMSTATE TO CURRENT FOLDER
REM --
SET DRV=%CD:~0,1%
SET DT=%date%
SET FNAME=%DRV%:\Backup\%DT:~0,4%%DT:~5,2%%DT:~8,2%-%COMPUTERNAME%-SystemConfig.bkf

ntbackup backup systemstate /D "system configuration %DT%" /F "%FNAME%"

 「SET DRV=%CD:~0,1%」は、カレント・ドライブを取り出すための指定である。タスク・スケジューラで自動起動する場合は、カレント・ドライブではなく、「C:」や「D:」など、特定のドライブを明示的に指定するのがよい。

 「SET DT=%date:~-10%」は、%date%変数の値のうち、最後の10文字をDTという変数にコピーするコマンドである。一度コピーしてから使用しているのは、%date%を3回呼び出している間に日付が変わってしまっても問題ないようにするためである(%date%では影響はほとんどないが、%time%を使う場合は、処理に時間がかかるとどんどん進んでしまい、不整合が生じる可能性がある)。

1日前の計算

 ところで以上の例では今日の日付を取り出してファイル名にしているが、実際には、前日の日付が欲しい場合も少なくない。例えば前日分のログファイルを別のサーバへコピーしたり、1カ月前のファイルを見つけ出して削除したり、といったケースが考えられる。残念ながら1日前とか1カ月前を計算して、変数にセットする簡単な方法はない。いちおう「SET /Aコマンド」を使えば数値計算もできるので、日付部分を1日前に戻すといった操作も不可能ではないが、月の初めや年の初め、うるう年の2月末日の処理なども考慮しなければならないので、非常に面倒である。あえてバッチ・ファイルで書くとすると、次のようになるだろうか。

※ファイル:prevdate.bat

set yy=%date:~0,4%
set mm=%date:~5,2%
set dd=%date:~8,2%
echo 今日は%yy%年、%mm%月、%dd%日です。
echo.

rem 1日前の日付を計算する

set /a dd=%dd%-1
set dd=00%dd%
set dd=%dd:~-2%
set /a ymod=%yy% %% 4

if %dd%==00 (
if %mm%==01 (set mm=12&& set dd=31&& set /a yy=%yy%-1)
if %mm%==02 (set mm=01&& set dd=31)
if %mm%==03 (set mm=02&& set dd=28&& if %ymod%==0 (set dd=29))
if %mm%==04 (set mm=03&& set dd=31)
if %mm%==05 (set mm=04&& set dd=30)
if %mm%==06 (set mm=05&& set dd=31)
if %mm%==07 (set mm=06&& set dd=30)
if %mm%==08 (set mm=07&& set dd=31)
if %mm%==09 (set mm=08&& set dd=31)
if %mm%==10 (set mm=09&& set dd=30)
if %mm%==11 (set mm=10&& set dd=31)
if %mm%==12 (set mm=11&& set dd=30)
)

echo 1日前は、%yy%年、%mm%月、%dd%日です。

 だが、ここまでしてわざわざバッチ・ファイルで計算するのは、あまり勧められない(n日前にするといった応用が利かない)。こういった場合はWSHなどを呼び出して処理する方が簡単かもしれない。WSHを呼び出す方法については、Windows TIPSの「曜日や日付によって処理を切り替える(BAT File)」などを参考にしていただきたい。End of Article

  関連記事(Windows Server Insider)
  Windows TIPS:曜日や日付によって処理を切り替える(BAT File)
  Windows TIPS:OSの種類によってバッチ・ファイルの処理を切り替える方法
  Windows TIPS:スクリプトで使うftpコマンド
  連載:Windows 2000 コマンドライン徹底活用
  運用:Windows管理者のためのWindows Script Host入門
     
この記事と関連性の高い別のWindows TIPS
テキスト・ファイル中の文字列を環境変数にセットする(setx応用編)
setxで環境変数の値を設定する(基本編)
曜日や日付によって処理を切り替える(BAT File)
環境変数を変更する
WSHで環境変数を設定する
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

更新履歴
【2004/05/05】当初、%date%変数から数字の部分を抜き出す方法として「%date:~0,4%%date:~5,2%%date:~8,2%」を紹介しておりましたが、Windows 2000環境では日付文字列の先頭に曜日が表示されるのでこれでは正しく動作しないことが判明しました。そこでいったん「%date:~-10%」として、数字部分だけを取得する方法に変更し、関連する解説文を追加・変更しました。お詫びして訂正させていただきます。
【2007/10/12】%time%変数の取り扱いに関する注意点を追加しました。
 
「Windows TIPS」

ホワイトペーパーTechTargetジャパン

Windows Server Insider フォーラム 新着記事

@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

RSSフィード

スキルアップ/キャリアアップ(JOB@IT)

- PR -
@IT Sepcial
- PR -

お勧め求人情報

キャリアアップ 〜JOB@IT
@IT Sepcial
ソリューションFLASH