バッチファイルでzip圧縮する(PowerShellを使用)


Y子です。
今日はファイルを圧縮してみます。

概要・用途

PowerShellを使って、zip圧縮します。
自動処理の中で、圧縮してサイズを小さくしたり、複数ファイルを1ファイルにまとめたり、等の用途を想定します。
確認環境:Windows 10 Home (Bld. 19042.928)

コード

(1) 1ファイルを圧縮する

1つのファイルを圧縮して、1つのzipファイルを作ります。
zipファイルの置き場所は、元ファイルと同じフォルダとします。
zipファイルのファイル名は、元ファイルの末尾に「.zip」を追加しただけとします。

compress_file_s2s.bat
@echo off
setlocal

rem 引数がない場合は終了する
if "%~1"=="" (echo 引数がありません & pause & exit /b)

rem 圧縮前ファイル
set str_file=%~1

rem 圧縮後ファイル
set str_zipfile=%str_file%.zip

rem zip圧縮実行
powershell compress-archive -Path '%str_file%' -DestinationPath '%str_zipfile%' -Force
echo %str_zipfile%

endlocal
pause

このバッチファイルに、C:\work dir\test01.txtをマウスでドロップした結果は、以下の通りです。

実行結果
C:\work dir\test01.txt.zip
続行するには何かキーを押してください . . .

なお、半角スペースを含むパスを扱う際、PowerShellでは'シングルクオート'で囲まないといけないようですね。
バッチファイルの中では'シングルクオート'でも"ダブルクオート"でも行けたので、ちょっと悩みました。

(2) 複数ファイルをそれぞれ圧縮する

n個のファイルを圧縮して、同数のzipファイルを作ります。
zipファイルの置き場所は、元ファイルと同じフォルダとします。
zipファイルのファイル名は、元ファイルの末尾に「.zip」を追加しただけとします。
複数の引数を処理する方法は、この記事で確認したやり方です。

compress_file_m2m.bat
@echo off
setlocal

:label_top

rem 引数がない場合は最後に飛んで終了する
if "%~1"=="" (
  goto :label_bottom
)

rem 圧縮前ファイル
set str_file=%~1

rem 圧縮後ファイル
set str_zipfile=%str_file%.zip

rem zip圧縮実行
powershell compress-archive -Path '%str_file%' -DestinationPath '%str_zipfile%' -Force
echo %str_zipfile%

rem 引数をシフトし、最初に戻る
shift
goto :label_top

:label_bottom
echo 処理を終了しました
endlocal
pause

このバッチファイルに、C:\work dir\フォルダ中の5個のファイルをマウスでドロップした結果は、以下の通りです。

実行結果
C:\work dir\test01.txt.zip
C:\work dir\test02.txt.zip
C:\work dir\test03.zi_.zip
C:\work dir\test04.txt.zip
C:\work dir\test05.zi.zip
処理を終了しました
続行するには何かキーを押してください . . .   

(3) 複数ファイルをひとつに圧縮する

n個のファイルをまとめて圧縮して、1個のzipファイルを作ります。
zipファイルの置き場所は、元ファイルと同じフォルダとします。
zipファイルのファイル名は、「zipfile_日付_時刻.zip」とします。

compress_file_m2s.bat
@echo off
setlocal

rem 日付「20210402」形式
set str_date=%date:~0,4%%date:~5,2%%date:~8%

rem 時刻「094617」形式
set str_time=%time: =0%
set str_time=%str_time:~0,2%%str_time:~3,2%%str_time:~6,2%

rem 圧縮前ファイル(初期化)
set str_file=

rem 圧縮後ファイル
set str_zipfile=zipfile_%str_date%_%str_time%.zip

:label_top

rem 引数がない場合は最後に飛んで終了する
if "%~1"=="" (
  goto :label_bottom
)

rem 圧縮前ファイル(カンマでつなげる)
if "%str_file%"=="" (
  set str_file='%~1'
) else (
  set str_file=%str_file%,'%~1'
)

rem 引数をシフトし、最初に戻る
shift
goto :label_top

:label_bottom

if not "%str_file%"=="" (
  rem zip圧縮実行
  powershell compress-archive -Path %str_file% -DestinationPath '%str_zipfile%' -Force
  echo %str_zipfile%
)

echo 処理を終了しました
endlocal
pause

このバッチファイルに、C:\work dir\フォルダ中の5個のファイルをマウスでドロップした結果は、以下の通りです。

実行結果
zipfile_20210426_192651.zip
処理を終了しました
続行するには何かキーを押してください . . .

おわりに

小さいファイルがたくさんあると、フォルダの表示やコピーに時間がかかったりします。
バックアップ処理を自動化するような場合、元のファイルのまま保存しておくより、zipファイルにパッキングしてしまった方が扱いやすい場合も多いように思います。
そんな時に、今回のコードが使えそうですね。

ではではー!