連載
» 2015年07月01日 05時00分 公開

Tech TIPS:Windowsのバッチファイル中で日付をファイル名に使用する (2/2)

[打越浩幸, 島田広道,デジタルアドバンテージ]
前のページへ 1|2       

●実際の利用例(バックアップした日がすぐ分かるようにフォルダをバックアップする)

 この手法を利用して、例えばrobocopyコマンドで過去のバックアップを残しつつ、特定のフォルダをバックアップする例を説明しよう。

 バックアップの保存先としては、このバッチファイルを起動したドライブの「\Backup」というフォルダの直下に、バックアップした日付を含む名前のサブフォルダを作成して利用する。これにより過去のバックアップは上書きされずに別々のサブフォルダに保存されていく。

 また、このサブフォルダをどこか別のシステムへコピーして保存することを考え、サブフォルダ名にはサーバ名も含めるようにしている(ファイル名の最後に「-%COMPUTERNAME%」などを付けてコンピュータ名を付加する)。これにより、どのシステムでいつバックアップしたかがすぐに分かるようになる。

※ファイル: backupcmd.cmd

setlocal

set drv=%cd:~0,1%
set dt=%date%
set FName=%drv%:\Backup\%dt:~-10,4%%dt:~-5,2%%dt:~-2,2%-%COMPUTERNAME%

robocopy c:\datafiles "%FName%" /mir

endlocal



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

 「set dt=%date%」で、いったんdate変数をdtという変数にコピーしているのは、date変数を3回参照している間に日付が変わってしまっても問題がないようにするためである。

 このテクニックはdate変数より、むしろtime変数を使う場合に有用だろう。なぜなら、処理に時間がかかるとtime変数の値はどんどん進んでしまい、不整合が生じる可能性があるからだ。

 なお、「%date%」を実行してから「%time%」を実行するまでの間に日付が変わる可能性もわずかながらある。それが心配なら、次のようにIF文を追加で実行して、「%date%」を再取得するとよいだろう。

set dt=%date%& set tm=%time%
if "%tm:~0,5%"==" 0:00" set dt=%date%

※00時00分の場合は、日付が前日の可能性があるので再取得する



●1日前の計算

 以上の例では今日の日付を取り出してフォルダ名の一部に用いている。しかし実際には、前日の日付が欲しい場合も少なくない。例えば前日分のログファイルを別のサーバへコピーしたり、1カ月前のファイルを見つけ出して削除したり、といったケースが考えられる。

 だが残念なことに、1日前とか1カ月前を計算して、変数にセットする簡単な方法はない。

 一応「set /a」コマンドを使えば数値計算もできるので、日付部分を1日前に戻すといった操作も不可能ではない。しかし、月の初めや年の初め、うるう年の2月末日の処理なども考慮しなければならないので、非常に面倒である。

 あえてバッチファイルで書くとすると、次のようになるだろうか。

※ファイル:prevdate.cmd

setlocal

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

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

set /a dd=1%dd%-101
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%日です。

endlocal



 だが、ここまでしてわざわざバッチファイルで計算するのは、あまり勧められない。n日前にするといった応用が利かないからだ。

 こういった場合はWSHやPowerShellで処理する方が簡単かもしれない。WSHを利用する方法については、TIPS「曜日や日付によって処理を切り替える(BAT File)」などを参考にしていただきたい。

■更新履歴

【2015/07/01】Windows 8/Windows 8.1/Windows 10プレビュー、およびWindows Server 2012/Windows Server 2012 R2での動作を確認しました。

【2011/08/26】「1日前の計算」のprevdate.batにて、日付が8日または9日のときにエラーが発生する不具合と、Windows 2000で年月日を正しく抽出できなかった不具合を修正しました。以上、おわびして訂正いたします。また、Windows Server 2008/Windows 7/Windows Server 2008 R2での動作を確認しました。さらに、例として採りあげていたntbackupコマンドがWindows Vista以降で利用できなくなったため、代わりにrobocopyによるフォルダバックアップの例に差し替えました。

【2007/10/12】%time%変数の取り扱いに関する注意点を追加しました。

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

【2004/05/01】初版公開(対象はWindows 2000/Windows XP/Windows Server 2003)。


「Tech TIPS」のインデックス

Tech TIPS

前のページへ 1|2       

Copyright© 1999-2017 Digital Advantage Corp. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。