バッチファイルからZIPファイルを自動解凍したい場面は多くあります。定期的に届くZIPを自動展開してから処理する、ビルド成果物をZIPで受け取って展開する、大量のZIPをまとめて解凍するなど、自動化のニーズは様々です。
この記事では、Windows標準の tarコマンド・PowerShell(Expand-Archive)・7-Zip の3方式を比較しながら、一括解凍・エラー処理・パスワード付きZIP対応まで実践的に解説します。
- tar・PowerShell・7-Zip の比較と選び方
- 各方法の基本形とエラー処理付き実装
- フォルダ内のZIPを一括解凍する方法
- パスワード付きZIPの解凍
- 解凍前に中身を確認するドライラン
- よくある落とし穴5選と対策
- 実践例3本・FAQ6問
1. 解凍方法の比較と選び方
| 方法 | 必要環境 | メリット | デメリット |
|---|---|---|---|
| tarコマンド | Windows 10 1803以降 | 追加インストール不要・高速 | 古いWindowsでは使えない |
| PowerShell Expand-Archive |
Windows 7以降(PS3以上) | 追加インストール不要・エラー処理しやすい | 大容量ZIPでやや遅い |
| 7-Zip | 別途インストール必要 | 高速・多形式対応・パスワード付き対応 | インストール必須 |
社内端末で追加インストールできないなら tarコマンドまたはPowerShell、パスワード付きや大量ZIPを高速処理するなら 7-Zip が最適です。
2. tarコマンドで解凍する(Windows 10以降標準)
Windows 10 バージョン1803以降、Windowsに標準搭載されたtarコマンドでZIPを解凍できます。追加インストール不要で最も手軽な方法です。
基本形
@echo off
setlocal
set "ZIP_FILE=C:\work\archive.zip"
set "OUT_DIR=C:\work\extracted"
:: 解凍先フォルダを作成(存在しない場合)
if not exist "%OUT_DIR%" mkdir "%OUT_DIR%"
:: tar で解凍(-x:展開 -f:ファイル指定 -C:出力先)
tar -xf "%ZIP_FILE%" -C "%OUT_DIR%"
if errorlevel 1 (
echo [ERROR] 解凍に失敗しました: %ZIP_FILE%
exit /b 1
)
echo [OK] 解凍完了: %OUT_DIR%
tarオプション早見表
| オプション | 意味 | 使用例 |
|---|---|---|
-x |
展開(extract) | tar -x |
-f |
ファイル名を指定 | tar -xf archive.zip |
-C |
出力先ディレクトリ | tar -xf a.zip -C C:\out |
-v |
詳細表示(verbose) | tar -xvf a.zip |
-t |
中身の一覧表示(解凍しない) | tar -tf a.zip |
ZIP名から解凍先フォルダ名を自動生成する
@echo off
setlocal enabledelayedexpansion
set "ZIP_FILE=C:\work\archive.zip"
:: ZIPのファイル名(拡張子なし)を取得して解凍先フォルダ名にする
for %%F in ("%ZIP_FILE%") do set "BASE=%%~nF"
for %%F in ("%ZIP_FILE%") do set "DIR=%%~dpF"
set "OUT_DIR=%DIR%%BASE%"
if not exist "%OUT_DIR%" mkdir "%OUT_DIR%"
tar -xf "%ZIP_FILE%" -C "%OUT_DIR%"
echo 解凍先: %OUT_DIR%
3. PowerShell(Expand-Archive)で解凍する
PowerShellの Expand-Archive コマンドレットはWindows 7以降(PowerShell 3.0以上)で使用できます。PowerShellをバッチから呼び出す方法と合わせて参照してください。
基本形
@echo off
setlocal
set "ZIP_FILE=C:\work\archive.zip"
set "OUT_DIR=C:\work\extracted"
if not exist "%OUT_DIR%" mkdir "%OUT_DIR%"
powershell -NoProfile -Command "Expand-Archive -Path '%ZIP_FILE%' -DestinationPath '%OUT_DIR%'"
if errorlevel 1 (
echo [ERROR] 解凍失敗
exit /b 1
)
echo [OK] 解凍完了
上書き・強制展開(-Force オプション)
既に解凍先にファイルがある場合は -Force を付けると上書き展開します。
powershell -NoProfile -Command "Expand-Archive -Path '%ZIP_FILE%' -DestinationPath '%OUT_DIR%' -Force"
パスにスペースが含まれる場合
パスにスペースがあっても、PowerShell に渡す文字列内で シングルクォート(’) を使うと安全に解凍できます。パスにスペースが含まれているとエラーになるときの解決策も参照してください。
@echo off setlocal set "ZIP_FILE=C:\my work\data archive.zip" set "OUT_DIR=C:\my work\extracted" :: 外側を " で囲み、内側パスを シングルクォート ' で囲む :: → %ZIP_FILE% が展開された後に PowerShell が ' で文字列を認識するため、スペースが含まれていても正しく動作する powershell -NoProfile -Command "Expand-Archive -Path '%ZIP_FILE%' -DestinationPath '%OUT_DIR%' -Force"
4. 7-Zipで解凍する(高機能・高速)
7-Zipはフリーの高機能圧縮/解凍ツールです。ZIP以外にもRAR・7z・tarなど多くの形式に対応し、パスワード付きZIPの解凍や大量ファイルの高速処理に適しています。
基本形
@echo off
setlocal
set "SEVENZIP=C:\Program Files\7-Zip\7z.exe"
set "ZIP_FILE=C:\work\archive.zip"
set "OUT_DIR=C:\work\extracted"
:: 7-Zip の存在確認
if not exist "%SEVENZIP%" (
echo [ERROR] 7-Zip が見つかりません: %SEVENZIP%
echo https://www.7-zip.org/ からインストールしてください
exit /b 1
)
if not exist "%OUT_DIR%" mkdir "%OUT_DIR%"
:: x:フル展開 -o:出力先(スペースなし)-y:確認スキップ
"%SEVENZIP%" x "%ZIP_FILE%" -o"%OUT_DIR%" -y
if errorlevel 1 (
echo [ERROR] 7-Zip による解凍に失敗しました
exit /b 1
)
echo [OK] 解凍完了: %OUT_DIR%
7-Zipの主要オプション
| オプション | 意味 |
|---|---|
x |
フルパスを維持して展開(推奨) |
e |
フラットに展開(フォルダ構造なし) |
-o"パス" |
出力先(-o と ” の間にスペース不要) |
-y |
確認プロンプトをすべてYes |
-p"パスワード" |
パスワード指定 |
-aoa |
既存ファイルをすべて上書き |
-aos |
既存ファイルをすべてスキップ |
l |
中身の一覧表示(解凍しない) |
パスワード付きZIPを解凍する
パスワード付きZIPは7-Zipのみで対応できます(tar・PowerShellは非対応)。パスワード付きZIPを自動生成する方法も参照してください。
@echo off
setlocal
set "SEVENZIP=C:\Program Files\7-Zip\7z.exe"
set "ZIP_FILE=C:\work\secure.zip"
set "OUT_DIR=C:\work\extracted"
set "ZIP_PASS=MyP@ssw0rd"
if not exist "%OUT_DIR%" mkdir "%OUT_DIR%"
"%SEVENZIP%" x "%ZIP_FILE%" -o"%OUT_DIR%" -p"%ZIP_PASS%" -y
if errorlevel 1 (
echo [ERROR] パスワードが違うか、ファイルが破損しています
exit /b 1
)
echo [OK] パスワード付きZIP解凍完了
set /p で読み込む、または実行時に入力させる設計にしましょう。
5. フォルダ内のZIPを一括解凍する
5-1. カレントフォルダ内のZIPをすべて解凍
@echo off
setlocal enabledelayedexpansion
set "BASE_DIR=C:\work\zips"
set "CNT=0"
set "ERR=0"
for %%F in ("%BASE_DIR%\*.zip") do (
:: ZIPのファイル名(拡張子なし)を解凍先フォルダ名にする
set "OUT=%BASE_DIR%\%%~nF"
if not exist "!OUT!" mkdir "!OUT!"
echo 解凍中: %%~nxF -^> !OUT!
tar -xf "%%F" -C "!OUT!"
if errorlevel 1 (
echo [ERROR] %%~nxF の解凍失敗
set /a ERR+=1
) else (
set /a CNT+=1
)
)
echo ===== 完了: 成功 !CNT! 件 / 失敗 !ERR! 件 =====
if !ERR! GTR 0 exit /b 1
5-2. サブフォルダ再帰的に一括解凍(for /r)
@echo off
setlocal enabledelayedexpansion
set "ROOT=C:\work"
set "CNT=0"
for /r "%ROOT%" %%F in (*.zip) do (
:: 各ZIPと同じフォルダに解凍先を作成
set "OUT=%%~dpF%%~nF"
if not exist "!OUT!" mkdir "!OUT!"
echo 解凍中: %%~fF
tar -xf "%%F" -C "!OUT!" && set /a CNT+=1
)
echo 合計 !CNT! 件を解凍しました
5-3. 7-Zip で大量ZIPを並列解凍(高速化)
ZIPファイルが数十本以上ある場合は、start /b で並列処理すると高速です。大量ファイルを並列処理する方法を参照してください。
@echo off
setlocal enabledelayedexpansion
set "SEVENZIP=C:\Program Files\7-Zip\7z.exe"
set "BASE_DIR=C:\work\zips"
set "MAX_JOBS=4"
set "JOBS=0"
for %%F in ("%BASE_DIR%\*.zip") do (
set "OUT=%BASE_DIR%\%%~nF"
if not exist "!OUT!" mkdir "!OUT!"
:: バックグラウンドで解凍起動
start /b "" "%SEVENZIP%" x "%%F" -o"!OUT!" -y >nul 2>&1
set /a JOBS+=1
:: MAX_JOBS に達したら全完了を待つ
if !JOBS! GEQ !MAX_JOBS! (
call :wait_all
set JOBS=0
)
)
call :wait_all
echo 並列解凍完了
exit /b 0
:wait_all
timeout /t 2 /nobreak >nul
:check
tasklist /fi "imagename eq 7z.exe" 2>nul | find "7z.exe" >nul
if not errorlevel 1 (
timeout /t 1 /nobreak >nul
goto :check
)
exit /b 0
6. 解凍前に中身を確認する(ドライラン)
実際に解凍する前に、ZIPの中身をリストアップして確認できます。
@echo off
setlocal
set "ZIP_FILE=C:\work\archive.zip"
:: ── tar で中身を一覧表示(-t オプション)──
echo ===== ZIP の中身(tarコマンド)=====
tar -tf "%ZIP_FILE%"
:: ── PowerShell でファイル数とサイズを確認 ──
echo.
echo ===== ファイル一覧(PowerShell)=====
powershell -NoProfile -Command "$z=Add-Type -Assembly System.IO.Compression.FileSystem; [IO.Compression.ZipFile]::OpenRead('%ZIP_FILE%').Entries | Select-Object FullName,Length"
:: ── 7-Zip で中身を一覧(l コマンド)──
echo.
echo ===== ファイル一覧(7-Zip)=====
if exist "C:\Program Files\7-Zip\7z.exe" (
"C:\Program Files\7-Zip\7z.exe" l "%ZIP_FILE%"
)
7. 落とし穴5選と対策
落とし穴1:-o と出力先のスペースで失敗する(7-Zip)
:: NG: -o の後にスペースを入れると解凍先が無視される "7z.exe" x archive.zip -o "C:\output" :: OK: -o の直後にパスを書く(スペースなし) "7z.exe" x archive.zip -o"C:\output"
落とし穴2:PowerShell で変数展開がされない
:: NG: " 内の %VAR% は cmd で展開されない場合がある powershell -Command "Expand-Archive -Path "%ZIP_FILE%" -DestinationPath "%OUT_DIR%"" :: OK: 外側を " 内側を ' にする powershell -Command "Expand-Archive -Path '%ZIP_FILE%' -DestinationPath '%OUT_DIR%'" :: OK: -File でPowerShellスクリプトファイルに切り出す方法もある powershell -NoProfile -ExecutionPolicy Bypass -File extract.ps1
落とし穴3:tar でUTF-8ファイル名が文字化けする
:: 日本語ファイル名を含むZIPをtarで解凍すると文字化けすることがある :: 対策: 7-Zip または PowerShell を使う :: PowerShell は文字コードを自動処理してくれることが多い powershell -NoProfile -Command "Expand-Archive -Path '%ZIP_FILE%' -DestinationPath '%OUT_DIR%' -Force" :: 7-Zip は CodePage オプションで文字コードを指定可能 "C:\Program Files\7-Zip\7z.exe" x "%ZIP_FILE%" -o"%OUT_DIR%" -y -mcp=932
落とし穴4:既に解凍済みのファイルに何度も上書きしてしまう
:: NG: 毎回無条件に解凍するとファイルが上書きされる
tar -xf "%ZIP_FILE%" -C "%OUT_DIR%"
:: OK: 解凍先フォルダが存在する場合はスキップ
if exist "%OUT_DIR%\*" (
echo [SKIP] 既に解凍済みです: %OUT_DIR%
) else (
if not exist "%OUT_DIR%" mkdir "%OUT_DIR%"
tar -xf "%ZIP_FILE%" -C "%OUT_DIR%"
)
ファイルの存在確認については ファイルの存在チェックと条件分岐を行う方法を参照してください。
落とし穴5:tarの-Cオプションで解凍先が存在しないとエラーになる
:: NG: 解凍先フォルダが存在しないと tar がエラー終了する tar -xf "%ZIP_FILE%" -C "C:\new_folder" :: Error: Cannot change dir to C:\new_folder: No such file or directory :: OK: tar の前に必ず mkdir で作成する if not exist "C:\new_folder" mkdir "C:\new_folder" tar -xf "%ZIP_FILE%" -C "C:\new_folder"
tarと異なり、7-Zipの -o オプションは解凍先が存在しない場合に自動作成します。
8. 実践例3本
実践例1:ダウンロードフォルダの新しいZIPを自動解凍してアーカイブ
@echo off
setlocal enabledelayedexpansion
set "DOWNLOAD=C:\Users\%USERNAME%\Downloads"
set "ARCHIVE=C:\work\extracted"
set "DONE_DIR=C:\work\done_zips"
if not exist "%ARCHIVE%" mkdir "%ARCHIVE%"
if not exist "%DONE_DIR%" mkdir "%DONE_DIR%"
for %%F in ("%DOWNLOAD%\*.zip") do (
set "OUT=%ARCHIVE%\%%~nF"
:: 解凍済みチェック(解凍先フォルダが既にある場合はスキップ)
if exist "!OUT!" (
echo [SKIP] 解凍済み: %%~nxF
) else (
echo [解凍] %%~nxF ...
mkdir "!OUT!"
tar -xf "%%F" -C "!OUT!"
if errorlevel 1 (
echo [ERROR] %%~nxF の解凍失敗
rmdir "!OUT!" >nul 2>&1
) else (
:: 成功したらZIPをdoneフォルダへ移動
move "%%F" "%DONE_DIR%\" >nul
echo [OK] 解凍完了 -^> !OUT!
)
)
)
echo 処理完了
ファイルを削除する方法は ファイルを削除する方法完全ガイドも参照してください。
実践例2:毎日届くZIPを自動解凍してCSV処理
FTPサーバーなどに毎日届くZIPファイルを解凍し、中のCSVをコピーして処理するパターンです。
@echo off
setlocal enabledelayedexpansion
set "TODAY=%date:~0,4%%date:~5,2%%date:~8,2%"
set "ZIP_FILE=C:\sftp_in\data_%TODAY%.zip"
set "TMP_DIR=C:\work\tmp_%TODAY%"
set "CSV_DEST=C:\work\csv_in"
set "LOG=C:\work\daily_extract.log"
echo [%date% %time%] 開始 >> "%LOG%"
:: ZIPファイルの存在確認
if not exist "%ZIP_FILE%" (
echo [ERROR] ZIPが見つかりません: %ZIP_FILE% >> "%LOG%"
exit /b 1
)
:: 一時フォルダに解凍
if not exist "%TMP_DIR%" mkdir "%TMP_DIR%"
tar -xf "%ZIP_FILE%" -C "%TMP_DIR%"
if errorlevel 1 (
echo [ERROR] 解凍失敗 >> "%LOG%"
exit /b 1
)
:: CSVファイルをコピー
set "CSV_CNT=0"
for %%C in ("%TMP_DIR%\*.csv") do (
copy "%%C" "%CSV_DEST%\" >nul
set /a CSV_CNT+=1
)
echo [OK] CSV %CSV_CNT% 件をコピーしました >> "%LOG%"
:: 一時フォルダを削除
rd /s /q "%TMP_DIR%"
echo [%date% %time%] 完了 >> "%LOG%"
実践例3:7-Zipで複数形式のアーカイブをまとめて解凍
ZIP以外にも7z・RAR・tarなど複数形式が混在するフォルダを一括解凍するパターンです。
@echo off
setlocal enabledelayedexpansion
set "SEVENZIP=C:\Program Files\7-Zip\7z.exe"
set "BASE_DIR=C:\work\archives"
set "CNT=0"
set "ERR=0"
if not exist "%SEVENZIP%" (
echo [ERROR] 7-Zip が見つかりません
exit /b 1
)
:: ZIP・7z・rar・tar.gz を一括解凍
for %%E in (zip 7z rar gz tar) do (
for %%F in ("%BASE_DIR%\*.%%E") do (
set "OUT=%BASE_DIR%\%%~nF"
if not exist "!OUT!" mkdir "!OUT!"
echo 解凍中: %%~nxF [%%E]
"%SEVENZIP%" x "%%F" -o"!OUT!" -y >nul 2>&1
if errorlevel 1 (
echo [ERROR] %%~nxF
set /a ERR+=1
) else (
set /a CNT+=1
)
)
)
echo ===== 解凍完了: 成功 !CNT! 件 / 失敗 !ERR! 件 =====
if !ERR! GTR 0 exit /b 1
9. まとめ
バッチファイルでZIPを解凍する方法と使い分けの基準を整理しました。
| 場面 | 推奨方法 |
|---|---|
| Windows 10以降・追加インストールなし・シンプルに解凍 | tarコマンド |
| エラー処理・スクリプト制御を重視・旧Windowsも対応 | PowerShell(Expand-Archive) |
| パスワード付き・複数形式・大量ファイルの高速処理 | 7-Zip |
ZIP圧縮の作成方法は バッチファイルでZIP圧縮を実行する方法を参照してください。
FAQ
if not exist "%OUT_DIR%" mkdir "%OUT_DIR%" で作成してください。-Force オプションを付けていないとエラーになります。Expand-Archive -Path '...' -DestinationPath '...' -Force で上書き展開できます。-o "パス"(-o の後にスペース)と書くと正しく認識されません。-o"パス"(スペースなし)と書いてください。if not errorlevel 1)に del "%ZIP_FILE%" を実行します。誤削除を防ぐため、必ず解凍成功を確認してから削除してください。ファイルを削除する方法も参照してください。-mcp=932(Shift-JIS指定)を付けて試してください。-x、7-Zipの x コマンド)。フラットに展開したい場合は7-Zipの e コマンドを使います(ただしファイル名衝突に注意)。
