忍者ブログ

リリースフォルダのファイルを差し替えるバッチ

2023年01月25日
今回は珍しくバッチファイル。

不定期にリリースフォルダのファイルを差し替える作業が発生していて
それを自動化した。


手動での作業手順は以下の通り。
①配置用のファイル名を見て、リリース先を確認。
②リリースフォルダのファイルをローカルにバックアップ(ファイル名変更)
③配置用ファイルをリリースフォルダに上書きコピー

たったこれだけの作業ではあるけれど、
リリース関係の作業は失敗するとやばいのでMP消費が激しい。

いつもならVBScriptで作るところだけど、
ファイルのコピーはコマンドプロンプトで一発でできるので、
今回はバッチファイルで作ることにした。




手動での作業手順をコマンドの落とし込むのがメインストリーム。

バックアップは今日の日付を入れるので、8桁の日付文字を定義した。
バッチファイルでの変数定義はSetを使う。呼び出しは変数名を%%でくくる。

set strDate=_%date:~0,4%%date:~5,2%%date:~8,2%


エラー処理はお決まりなので、errorEndというモジュールを作った。
call:errorEnd 引数 でモジュールを呼び出せる。

モジュール側は:モジュール名で始めてexit /bでモジュール終了。


引数は%1を使う。~を使って加工ができるので非常に読みづらい。


実行確認は軽くググったところ、gotoを使った表現ばっかり出てきた。
最初はコピペして使ってたものの、可読性が悪いので
RCyesnoというモジュールを作った。

yes系の回答なら変数を定義して、変数が未定義だったらメッセージを出して処理を終了する。
変数が定義されてたら変数をクリアして戻るのが肝で、
クリアを忘れると、2回目にモジュールに飛んだときに何を入れてもyes系の回答として処理される。



初めてまともな(変数を使った)バッチファイルを作ったので、
作法がわからずめっちゃ時間かかった。


作業時にストレスのかからないメッセージ誘導と
作業結果をエビデンスとしてログに残す処理、
ソースコードの読みやすさのバランスを取るのに苦労した。

バッチは通常、実行コマンドがなにか表示するので、
メッセージを表示するコマンドを実行すると、同じ内容が2回表示されちゃう。
なので、バッチの頭に@echo offを指定する。

逆にログファイルに書き込む処理は、画面表示をしないので@echo offを指定すると
画面上に何も表示しない。


処理だけじゃなくて、画面表示やログ出力についても
ちゃんと設計してから作業に取り掛かるべきだった。


そんな感じで、以下ソース。テキストファイルは こちら


@echo off

rem 引数なしの場合は即終了
if "%1"=="" call:errorEnd "入力ファイルがありません。処理を終了します。"

set iFile=%~nx1
if %iFile%==updata.csv set upPath=E:\Upload\User\

rem 上記以外のファイルはNG
if not defined upPath call:errorEnd "非対応のファイルがドロップされました。終了します。"

rem バックアップ前にup先をDirコマンドで確認
@echo ■UP先フォルダ■
dir /a-d %upPath% | findstr :
@echo;
@echo;

set strPlace=_DR

rem ログファイル名をセット
set logName=%date:~0,4%%date:~5,2%%date:~8,2%_cmdLog%strPlace%.txt
echo -------■手動メンテ開始■------- > %logName%

rem 変数のセット
set fName=%~n1
set Ext=%~x1
set bkPath=C:\Users\Administrator\Desktop\WORK\backup\
set strDate=_%date:~0,4%%date:~5,2%%date:~8,2%

rem bk先ファイルのフルパス
set bkFullname=%bkPath%%fname%%strDate%%strPlace%%Ext%
echo bkFullname=%bkFullname% >> %logName%

rem up先ファイルのフルパス
set upFullname=%upPath%%fname%%Ext%
echo upFullname=%upFullname% >> %logName%

rem 持込ファイルのフルパス
set iFullname=%1
echo iFullname=%iFullname% >> %logName%

rem ファイルの存在確認 あれば進む なければ終了
if not exist %upFullname% call:errorEnd "配置先に同名のファイルがありません。処理を終了します。"

REM ########## 処理実行の確認01 ##########
call:echoPause "手動メンテ「%~nx1」を開始します。配置先:%upPath%"
call:RCyesno "配置先に同名のファイルを確認。バックアップを取得します。よろしいですか(Y/N)?" "バックアップを中止しました。終了します。"

echo; >> %logName%
echo ■作業前エビデンス■%upFullname% >> %logName%
dir %upFullname% | findstr /n %fName% >> %logName%

echo; >> %logName%
echo ■バックアップを取得しエビデンス出力■%bkFullname% >> %logName%
copy %upFullname% %bkFullname%
dir %bkFullname% | findstr /n %fName% >> %logName%

@echo;
@echo;
@echo 上記UP先フォルダの「%~nx1」を新しいファイルに置き換えます。(日時:「%~t1」、size:「%~z1」)

rem バックアップフォルダを開く
start "" %bkPath%


REM ########## 処理実行の確認02 ##########
call:RCyesno "ファイル配置しますか。(Y/N)?" "処理を中断しました。"

echo; >> %logName%
echo ■持ち込みファイルを配置しエビデンス出力■%upFullname% >> %logName%
copy /-Y %iFullname% %upFullname%
dir %upFullname% | findstr /n %fName% >> %logName%

rem up先に配置されていることを確認のため開く
start "" %upPath%

rem 作業後にup先をDirコマンドで確認
dir /a-d %upPath%

call:echoPause "処理が完了しました。ファイルのコピーが成功しているか配置先を確認してください。"
echo -------■手動メンテ終了■------- >> %logName%
exit


:errorEnd
rem エラーメッセージを出して終了する
echo 【errorEnd】%~1
echo;
pause
rem :errorEnd終了
exit

:echoPause
rem メッセージを表示して中断する
echo %~1
echo;
pause
exit /b

:RCyesno
rem %1のメッセージでY/Nを問う。Y以外は%2のメッセージを表示して終了する。yesFlagは要初期化
SET /P ANSWER=%~1
if /i {%ANSWER%}=={y} (set yesFlag=1)
if /i {%ANSWER%}=={yes} (set yesFlag=1)
if not defined yesFlag call:errorEnd %2
set yesFlag=
)
exit /b


rem 以下、作業メモ
rem %~dp0 rem drive path name.x
rem %1
rem %~p1 rem パス名のみ表示
rem %~n1 rem ファイル名のみ表示
rem %~x1 rem 拡張子のみ表示
rem %~nx1 rem ファイル名と拡張子を表示
rem %~a1 ファイルの属性を表示
rem %~t1 ファイルの更新日時を表示
rem %~z1 ファイルのサイズを表示
PR
Comment
  Vodafone絵文字 i-mode絵文字 Ezweb絵文字