こんにちは。チェシャ男です。(-皿-)
今回は、
【PowerShell でファイルやフォルダをZIP圧縮する方法】
についてご紹介します。
今回紹介する ”Compress-Archive” コマンドレットは PowerShell 5.0 で新たに追加されたものです。
Windows で圧縮といえばお馴染みの「ZIPファイル」を作成することができます。圧縮だけでなく書庫化して複数のファイルをひとまとめにできるのも魅力的ですね。
PowerShell 5.0 以降ではフリーソフトを使用しなくても圧縮することができるので”Lhaplus” などをインストールする必要もありませんね。
圧縮ファイルの解凍方法についてはこちら↓をご覧ください。
[blogcard url=”https://cheshire-wara.com/powershell/ps-cmdlets/item-file/expand-archive/”]もくじ
Compress-Archive でファイルを圧縮する
ファイル圧縮を行うコマンドレットに
Compress-Archive(→ コマンドレットの詳細はこちら)
というものがあります。
【コマンドレット】
Compress-Archive
【オプション】
パターン1
-Path <圧縮元ファイルパス>
-DestinationPath <圧縮ファイル出力先>
-CompressionLevel <圧縮レベル>
-Update
-Confirm
-WhatIf
パターン2
-DestinationPath <圧縮ファイル出力先>
-LiteralPath <圧縮元ファイル(リテラル)パス>
-CompressionLevel <圧縮レベル>
-Update
-Confirm
-WhatIf
【入力】
System.String[]
【出力】
System.IO.FileInfo
【エイリアス】
なし
ファイルを圧縮する
さっそく圧縮してみましょう。まずは単純に1つのファイルを圧縮してみます。
Compress-Archive -Path <ファイルパス> -DestinationPath <出力先.zip>
というように ”-Path” オプションで圧縮元のファイル名を指定し ”-DestinationPath” オプションで圧縮先のファイル名を指定しましょう。
PS C:\work> #圧縮元のファイル PS C:\work> Get-ChildItem ディレクトリ: C:\work Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 2016/11/13 2:15 0 File1.txt PS C:\work> #圧縮する PS C:\work> Compress-Archive -Path .\File1.txt -DestinationPath .\Test.zip PS C:\work> #圧縮の確認 PS C:\work> Get-ChildItem ディレクトリ: C:\work Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 2016/11/13 2:15 0 File1.txt -a---- 2016/11/13 2:54 116 Test.zip
圧縮元と圧縮先を指定するだけなので分かりやすい使い方ですね。
”-Path” で圧縮元を指定するだけではなくパイプラインで渡すこともできます。
PS C:\work> #圧縮元のファイル PS C:\work> Get-ChildItem ディレクトリ: C:\work Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 2016/11/13 2:15 0 File1.txt PS C:\work> #ファイルをパイプで指定 PS C:\work> .\File1.txt | Compress-Archive -DestinationPath .\Test.zip パイプラインの中央にあるドキュメント C:\work\File1.txt を実行できません。 発生場所 行:1 文字:1 + .\File1.txt | Compress-Archive -DestinationPath .\Test.zip + ~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (C:\work\File1.txt:String) []、RuntimeException + FullyQualifiedErrorId : CantActivateDocumentInPipeline PS C:\work> #""でファイル名を囲む PS C:\work> ".\File1.txt" | Compress-Archive -DestinationPath .\Test.zip PS C:\work> #圧縮の確認 PS C:\work> Get-ChildItem ディレクトリ: C:\work Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 2016/11/13 2:15 0 File1.txt -a---- 2016/11/13 2:58 116 Test.zip
実行結果を見ていただけるとわかると思いますが、パイプするファイル名を””(ダブルクォーテーション)等で囲んでいなければ失敗するようなので注意が必要ですね。
複数のファイルを圧縮する
先ほどは1つのファイルを圧縮したので今度は複数のファイルをまとめて圧縮してみましょう。
方法はいくつかありますが今回はわかりやすいように連番になっているファイルを”*(ワイルドカード)”で指定します。
PS C:\work> #圧縮元のファイル PS C:\work> Get-ChildItem ディレクトリ: C:\work Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 2016/11/13 20:52 0 File1.txt -a---- 2016/11/13 20:52 0 File2.txt -a---- 2016/11/13 20:52 0 File3.txt -a---- 2016/11/13 20:52 0 File4.txt -a---- 2016/11/13 20:52 0 File5.txt PS C:\work> #複数ファイルを圧縮 PS C:\work> Compress-Archive -Path .\File*.txt -DestinationPath Test.zip PS C:\work> PS C:\work> #圧縮の確認 PS C:\work> Get-ChildItem ディレクトリ: C:\work Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 2016/10/05 21:15 0 File1.txt -a---- 2016/11/13 20:52 0 File2.txt -a---- 2016/11/13 20:52 0 File3.txt -a---- 2016/11/13 20:52 0 File4.txt -a---- 2016/11/13 20:52 0 File5.txt -a---- 2016/11/17 3:05 492 Test.zip
ZIPファイルの中身も確認してみると、
となっているので問題なさそうですね。
“-Update” オプションで ZIP にファイルを追加する
すでに圧縮してまとめてしまった ZIP ファイルに対しては ”-Update” オプションを使ってファイルを追加することができます。
もしあなたがバックアップとしてZIP圧縮を使用しているとしたら、かなり便利ではありませんか!
Compress-Archive -Path <ファイルパス> -DestinationPath <出力先.zip> -Update
以下は実行例です。
PS C:\work> #追加するファイルを作成 PS C:\work> New-Item -Name .\File6.txt ディレクトリ: C:\work\. Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 2016/11/13 3:17 0 File6.txt PS C:\work> #圧縮ファイルにファイル追加 PS C:\work> Compress-Archive -Path .\File6.txt -DestinationPath .\Test.zip -Update
エクスプローラから実際にZIPファイルの中身を覗いてみましょう。
ご覧のようにファイルが追加されていますね。
フォルダを圧縮する
ファイル圧縮と同様にフォルダの圧縮も可能です。
圧縮方法もファイル圧縮時と同様に ”-Path” オプションで圧縮元を指定し ”-DestinationPath” オプションで圧縮先を指定します。
PS C:\work> #圧縮元を確認 PS C:\work> Get-ChildItem ディレクトリ: C:\work Mode LastWriteTime Length Name ---- ------------- ------ ---- d----- 2016/11/13 3:25 Folder1 PS C:\work> #フォルダ内に移動 PS C:\work> Set-Location .\Folder1\ PS C:\work\Folder1> PS C:\work\Folder1> #フォルダの中身 PS C:\work\Folder1> Get-ChildItem ディレクトリ: C:\work\Folder1 Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 2016/11/13 2:52 0 File1.txt -a---- 2016/11/13 2:52 0 File2.txt -a---- 2016/11/13 2:52 0 File3.txt -a---- 2016/11/13 2:52 0 File4.txt -a---- 2016/11/13 2:52 0 File5.txt PS C:\work\Folder1> #元の位置に戻る PS C:\work\Folder1> Set-Location .. PS C:\work> PS C:\work> #フォルダ圧縮 PS C:\work> Compress-Archive -Path .\Folder1\ -DestinationPath Test.zip PS C:\work> PS C:\work> #圧縮の確認 PS C:\work> Get-ChildItem ディレクトリ: C:\work Mode LastWriteTime Length Name ---- ------------- ------ ---- d----- 2016/11/13 3:25 Folder1 -a---- 2016/11/13 3:32 572 Test.zip
ZIP ファイルの中身も確認してみましょう。下図のように ZIP ファイルの中にファイルが圧縮格納されていることがわかります。
ちなみに図を見ていただくとわかるように、フォルダを圧縮した場合は
.. \ 圧縮先フォルダ(DestinationPath) \ 圧縮したフォルダ名(Path) \ フォルダの中身
という構造になることに注意してください。
“-CompressionLevel” で指定する圧縮レベル
”-CompressionLevel” オプションでは、圧縮ファイルを作成する時どのくらいの圧縮力・圧縮スピードで圧縮するか決めることができます。
高速圧縮を使用すると圧縮ファイルを作成するための時間が短く済みますがファイルサイズが大きくなってしまうという欠点もあります
逆に最適な圧縮率で圧縮させる場合は圧縮元のファイルサイズによっては長く時間がかかる場合があります。
このオプションで設定できる値は次の通りです。
- Fastest:
->処理時間を短縮するために利用可能な最速となる圧縮率を使用します。- NoCompression:
->圧縮しないで書庫化だけ行う。- Optimal:
->最適な圧縮率を適用する。処理時間はファイルサイズに依存する。(デフォルト)
効率をも考えながら状況によって使い分ける方がよさそうですね。
単にファイルのアーカイブや整理として圧縮なしで使うという方法もありだと思います。
Compress-Archive 使用時の注意点
ここまで、”Compress-Archive” コマンドレットの使用方法を紹介しましたが Microsoft には以下のように説明があります。
DESCRIPTION
The Compress-Archive cmdlet creates a zipped (or compressed) archive file from one or more specified files or folders. An archive file allows multiple files to be packaged, and optionally compressed, into a single zipped file for easier distribution and storage. An archive file can be compressed by using the compression algorithm specified by the CompressionLevel parameter.
Because Compress-Archive relies upon the Microsoft .NET Framework API System.IO.Compression.ZipArchive to compress files, the maximum file size that you can compress by using Compress-Archive is currently 2 GB. This is a limitation of the underlying API.
Compress Archive-Microsoft Developer Network/© 2017 Microsoft
大事なところをザックリ訳すと、現在コマンドレットで圧縮可能な最大サイズは2GBまでとなっているようです。
また、環境によっては日本語のファイル名を圧縮しようとすると文字化けする場合もあります。
[blogcard url=”https://cheshire-wara.com/powershell/ps-column/compress-archive-incident/”]( .Net Framework 4.5 以降を導入している場合は直接フレームワークの機能から圧縮することもできるみたいですね)
まとめ
ファイルやフォルダを圧縮したい場合は
Compress-Archive -Path <圧縮元> -Destination <圧縮先>
を使用する。
圧縮済みのZIPファイルにファイルを追加する場合は、
-Update
圧縮率を変更したい場合は、
-CompressLevel
を使用する。
チェシャ 男 さん
以下のようなディレクトリ構成で、
b.txtだけNoCompressionを指定する方法、もしご存知でしたら
ご教示頂けないでしょうか。
dir1配下にa.txtとdir2が存在し、dir2配下にはb.txtが存在する。
y.kさん
コメントありがとうございます。
特定のファイルだけ圧縮レベルを変更することは仕様的にできなそうです。
が、無理やりやるのであれば、
①直下ファイルを圧縮したZIPを作る(下記だとa.txtを指定
②無圧縮で追加したいファイルを-Updateで追加する。その際CompressionLevel を指定する
Compress-Archive .\dir1\a.txt -DestinationPath dir1.zip
Compress-Archive .\dir1\dir2\ -DestinationPath dir1.zip -Update -CompressionLevel NoCompression
で、可能だと思います。
2.67KBのb.txtを用意して実際に試したところ、
・dir丸ごとZIPにした場合には、245B
・後からNoCompressで追加した場合には2.87KB
となりました。
チェシャ 男 さん
ご回答ありがとうございました。
仕様的にできなさそうということで承知致しました。
ご提示頂いた手法も、試してみました。
複数のサブフォルダをサブフォルダ名.ZIPのファイル名で各々に作成することはできませんか
Hogeさん
コメントありがとうございます。
サブフォルダはサブフォルダ単位で、親フォルダは配下とサブフォルダでZIPファイルを作るとすると
以下のコードなどはいかがでしょうか!
Get-ChildItem -Recurse -Force -Directory | %{Compress-Archive -Path $_.FullName -DestinationPath "$($_.Name).zip"}
[…] 【チェシャわら】PowerShellとは、から学ぶ入門者の教科書-脱コマンドプロン… 【Compress-Archive】PowerShellでファイルやフォルダをZIP圧縮する方法https://cheshire-wara.com/powershell/ps-cmdlets/ […]