ファイルリストから読込んだzipファイルを展開するバッチ処理

ソフトウェア
OpenIconsによるPixabayからの画像

前回、zipファイルを収集するバッチを作成したので、引続き集めたzipファイルをまとめて展開する、zipファイル展開バッチを試作しました。

バッチ作成の経緯

諸事情から前回、zipファイルを一か所に集めるバッチを作成しました。今回は続けて集めたzipファイルを、一括して展開するDOSバッチ(expand_zipfiles.bat)を試作してみました。

DOSバッチ化したい事

バッチ化したい事はおおむね以下の通り。※現場で動かす機会があり、必要な要件を4に追加しました。

  1. ファイルリストを読込み、展開対象のzipファイルパスを取得する
  2. 展開対象のzipファイルは、格納フォルダ直下に展開する
  3. 必要に応じてzipファイル展開後、展開元のzipファイルを削除する
  4. 文字コードが「UTF-8」の場合、処理開始時に適用させる

作成したDOSバッチ

以上を踏まえて、以下の様なDOSバッチ(expand_zipfiles.bat)を作成しました。※要件4に対応するコードを追記しました。

expand_zipfiles.bat
@echo off
rem 文字コードがUTF-8の場合有効化
rem chcp 65001
rem 実行されているバッチが置かれているフォルダをカレントディレクトリにする
cd /d %~dp0
rem ローカル変数使用開始
setlocal
rem 変数設定
set list=workfolder.csv
set targetPath=""
set workdir=.\collect
set copyST=""
set delflg=1

rem 作業フォルダのパスリストが無ければ処理エラー
if not exist %list% (
  echo 作業フォルダのパスリストがありません。
  goto ERROR
)

rem 作業フォルダが無ければ処理エラー
if not exist %workdir% (
  echo 作業フォルダがありません。
  goto ERROR
)

rem ループ中での変数使用設定
setlocal enabledelayedexpansion

rem for /fオプション 変数名 in (ファイル名) do コマンド
rem /fオプション:ファイルまたはコマンドの実行結果を行単位で変数に読込む
rem --------------------------------------------------------------------
rem CSVファイルの各行を読込み、1,3カラム目(作業フォルダとコピー状態)の
rem 値を取得する
for /f "tokens=1,3 delims=," %%i in (!list!) do (
  rem 作業フォルダパスとコピー状態を取得
  set targetPath=%%i
  set copyST=%%j

  rem コピー状態が「success」時のみ作業フォルダ下のzipファイルを展開する
  if !copyST!=="success" (
    rem powershellを使ったzipファイル展開
    powershell expand-archive -Path !targetPath!\*.zip -DestinationPath !targetPath! -Force
    rem 削除フラグONの時→展開元zipファイルを削除する
    if !delflg! equ 1 (del /q !targetPath!\*.zip)
  )
)

rem ローカル変数使用終了
endlocal

:ERROR
rem 一時停止「続行するには何かキーを押してください… 」を表示して処理を抜ける
pause
@echo on

コマンド説明

バッチの構成は前回作成したzipファイル取集バッチから流用し、基本事項ついては、初回に作成したバッチに詳細な説明があります。これらと被る箇所については説明を省いておりますので、そちらをご参照下さい。※要件4に対応した説明を末尾に追記しました。

ファイルリスト指定(set list=workfolder.csv)

ファイルリストには、前回作成した zipファイル収集バッチが出力する csvファイル(workfolder.csv)を指定します。本ファイルは、バッチ内のコピー処理で使用した「格納先パス(図1緑枠A列)」「取得先パス(図1緑枠B列)」「コピー状態(図1緑枠C列)」が、この順で行ごとに出力されています(図1赤枠1~3行)。ここから必要データ(格納先パス、コピー状態)を抜き出して、作業フォルダのパスリストとして活用します。

※「処理ファイル名(図1黄枠D列)」は、zipファイル収集バッチに新たに追加した「処理ファイル名も取得する」要件に対応した追加項目です。図1黄枠4行目も「パスに半角スペースが含まれる処理ファイルも扱う」要件に対応したテストデータです。

作業フォルダのパスリストの存在チェック

バッチの性質上、作業フォルダのパスリスト(workfolder.csv)が無い事態は考えにくいですが、念のため、存在チェック「if not exist %list% (~」をしています。作業フォルダのパスリストが無かった場合、その旨エラーメッセージ表示して、エラーハンドラ(:ERROR)に飛び、処理を抜けます。

作業フォルダの存在チェック

作業フォルダ(set workdir=.\collect)は、前回 zipファイル収集バッチが作成したフォルダです。本フォルダが無い事態も考えにくいですが、念のため、存在チェック「if not exist %workdir% (」をしています。作業フォルダが無かった場合、その旨エラーメッセージ表示して、エラーハンドラ(:ERROR)に飛び、処理を抜けます。

作業フォルダのパスリストを読込む

for /f “tokens=1,3 delims=,” %%i in (!list!) do (」にて、作業フォルダのパスリスト(workfolder.csv)の各行を読込み、1,3カラム目(図1緑枠A列:作業フォルダ、C列:コピー状態)の値を取得します。「tokens=1,3」にて取得列を指定「delims=,」にて列区切り文字を指定しています。

値を受ける変数は、forループの文法通りアルファベッド1文字「%%i」で1列目の値取得すれば、以降アルファベッド順に値が入る(例:%%aの値取得で 2列目がb,3列目がc…)仕組みになっているようです。ここでは更に、値の意味を明示する変数に代入(作業フォルダパス(set targetPath=%%i)とコピー状態(set copyST=%%j))し直して、以降の処理を行っています。

作業フォルダ下のzipファイルを展開する

今回のメイン処理です。「if !copyST!==”success” (」にて、コピー状態が「success」時のみ、zipファイルの展開を行う事とします。「powershell expand-archive -Path !targetPath!*.zip -DestinationPath !targetPath! -Force」にて、zipファイルの展開を行っています。

DOS環境には、zipファイルを展開するコマンドが無いため「powershell expand-archive」で、コマンドプロンプトから「PowerShell」のzipファイル解凍コマンド「expand-archive」を呼出して、zipファイルを展開しています。「-Path !targetPath!*.zip -DestinationPath !targetPath! -Force」は、コマンドのオプション部の記述です。

「-Path !targetPath!*.zip」で、展開元に作業フォルダパス直下のzipファイルを指定し、「-DestinationPath !targetPath!」で、展開先に作業フォルダパス直下を指定しています。「-Force」で、展開先ファイルの上書きを許可しています。

削除フラグONの時→展開元zipファイルを削除する

ファイル展開処理後の zipファイルは、削除する/削除しないで意見が割れたので、本バッチ処理内にzipファイルの削除フラグ(set delflg=1)を設け、現状デフォルトでONとしています。

「if !delflg! equ 1 (del /q !targetPath!\*.zip)」にて、削除フラグON(delflg equ 1)時、確認メッセージを表示せずに、展開元の作業フォルダパス直下のzipファイルを削除(del /q !targetPath!\*.zip)しています。

文字コードが「UTF-8」の場合

実際にバッチが動作する環境では、そのまま動かすと出力が文字化けしました。そのため、バッチの先頭に「chcp」コマンドにより、コマンドプロンプトで使用する文字コードを、あらかじめ変更する処理を挿入しました。今回は「Unicode (UTF-8)」に変更(chcp 65001)する事で、出力時の文字化けを解消できました。普段動かすときは不要のため、コメントアウトする事にしました。

動作確認

テスト環境の事前準備

zipファイル展開バッチ(expand_zipfiles.bat)は、前回作成したzipファイル収集バッチ(collect_listfiles.bat)動作後の使用を前提としているので、下図の通り前回使用した作業フォルダ下の「C:\work01」に配置しました(図2赤枠)。テストで使用するファイルリストには、前回作成した zipファイル収集バッチが出力した csvファイル(workfolder.csv)をそのまま(図1)流用します(図2青枠)。

本バッチ(expand_zipfiles.bat)は、zipファイル格納フォルダ「collect」配下のzipファイルを展開します。「collect」直下には、ファイルリスト(図1:A1~A3)に記載のフォルダ(expand001~expand003)が配置されています(図3#1)。ファイルリストに記載の通り、処理success(図1:C1,C3)フォルダ(expand001、003)下にはzipファイルが格納され(図3#2)、処理error(図1:C2)フォルダ(expand002)下は空フォルダになっています(図3#3)。図3#1緑枠は、zipファイル収集バッチにて、新規追加された「処理ファイルのパスに半角スペースが含まれる事を考慮」要件に対応して、追加されたフォルダ(expand004)です。

「処理ファイルのパスに半角スペースが含まれる事を考慮」要件に対応して追加された「expand004」フォルダ配下には、ファイル名に半角スペースが含まれるzipファイルが格納されます(追加図1)。

テスト

テスト環境でのバッチ処理

バッチ配置フォルダ(C:\work01)を開き、バッチ本体(expand_zipfiles.bat)をダブルクリックで起動します。ファイルリスト(workfolder.csv)が上から順に読込まれ、zipファイルの展開処理が行われます。途中「PowerShell」のコマンドが呼び出される箇所で、画面背景が青緑色に表示されますが、正常に稼働しているので処理を待ちます(図4)。

図4:「PowerShell」のコマンドが呼び出される箇所で、画面が青緑色に表示される

下図のようなDOS画面が表示されて、処理が終了しました(図5)。

図5:バッチ本体(expand_zipfiles.bat)終了時のDOS画面

テスト結果確認

zipファイルの格納フォルダ(collect)の確認

zipファイルの格納フォルダ(collect)配下の、個々のzipファイルが配置された「expand001~expand003」フォルダを確認します。ファイルリスト(workfolder.csv)の通り「expand001、003」フォルダ下には、zipファイルが格納され(図3#2)「expand002」フォルダは空フォルダになっています(図3#3)。「expand004」フォルダは、「処理ファイルのパスに半角スペースが含まれる事を考慮」要件に対応して新しく追加されたフォルダです(追加図2)

zipファイルの展開状況の確認

「expand001」フォルダ下のzipファイルは全展開(図6#1赤枠)され、展開元のzipファイルは削除(図6#1青枠)されており「expand003」フォルダ下のzipファイルも同様に展開(図6#2赤枠)される事を確認しました。また、zipファイルの削除フラグがON(set delflg=1)のため、展開元のzipファイルは、削除される事も確認できました(図6#1,#2青枠)。

「expand004」フォルダ下のzipファイルも、前述のzipファイルと同様に、全展開(追加図2赤枠)され、展開元のzipファイルは削除(追加図2緑枠)されており「処理ファイルのパスに半角スペースが含まれた」zipファイルも、正常に展開される事を確認できました(追加図2)。

空フォルダの確認

zipファイルが無い「expand002」フォルダ配下は処理対象外のため、何も変化しないことを確認しました(図7)。

図7:zipファイルが無いフォルダ下は、何も変化しない

エラー処理の確認

バッチ配置フォルダのパスリストが無い場合

バッチ配置フォルダ(C:\work01)を開き、ファイルリスト名(workfolder.csv)をリネーム(_workfolder.csv)し(図8赤枠)zipファイル展開バッチ(expand_zipfiles.bat)を起動します。

図8:バッチ配置フォルダのファイルリスト名をリネーム「workfolder.csv → _workfolder.csv」

バッチ処理を抜け「作業フォルダのパスリストがありません。」と表示され処理が終了します(図9赤枠)。期待通りに動作する事を確認できました。

図9:「作業フォルダのパスリストがありません。」と表示され処理が終了する

zipファイルの格納フォルダ(collect)が無い場合

zipファイルの格納フォルダ(collect)をリネーム(_collect)し(図10赤枠)zipファイル展開バッチ(expand_zipfiles.bat)を起動します。

図10:zipファイルの格納フォルダをリネーム「collect → _collect」

バッチ処理を抜け「作業フォルダがありません。」と表示され処理が終了します(図11赤枠)。期待通りに動作する事を確認できました。

図11:「作業フォルダがありません。」と表示され処理が終了する

その他確認

zipファイル削除フラグOFFにした場合の挙動確認を行います。

zipファイル削除フラグOFFの場合

zipファイル削除フラグOFF(set delflg=0)とし、zipファイル展開バッチ(expand_zipfiles.bat)を起動します。

set delflg=0

zipファイルの展開状況の確認のため代表例として、zipファイルの格納フォルダ(collect)配下の「expand001」フォルダを開きます。本フォルダ配下に、ファイル展開後もzipファイルが残っている事を確認できました(図12赤枠)。

図12:「expand001」フォルダ配下に、ファイル展開後もzipファイルが残っている事を確認

参考文献

コメント

タイトルとURLをコピーしました