今回はファイルをZIP圧縮してみます。Webからダウンロードした怪しい画像や、他人には見られてはいけないファイルなどは、どこかに隠しておくのが安全(?)です。もっとも、ディレクトリ(フォルダ)内容を暗号化しておけば安全ではあります。MacだとFileVaultというのがあり、設定すればディスクを暗号化できます。

 また、Windows 10 Proであればディレクトリ(フォルダ)内容を暗号化できます。UbuntuなどLinux系にも暗号化するためのソフトがあります。

https://support.microsoft.com/ja-jp/windows/ファイルを暗号化する方法-1131805c-47b8-2e3e-a705-807e13c10da7

 暗号化ソフトは検索すると結構たくさんあり、好みのものを使えばよさそうです・・・が、私は、この機能は怖いので使っていません。パスワードを忘れてしまう危険性があるからです。ある日パスワードが思い出せず四苦八苦するかもしれません。いや、パスワードをかけたこと自体忘れてしまうかもしれません。そうなると、いざとなったら強引な方法(総当たり)であれパスワード解除できてしまうソフトがいくつかあるパスワード付きZIPの方が妙な安心感があります(!?)

 なお、今回はUNIX系のシェル(bash,zsh)とMac版のPowerShellが対象です。Windows版のPowerShellでのZIP圧縮・解凍については次回にします。(長くなってしまったので)

ファイル一覧を表示

 と、その前に圧縮するファイルを選定する必要があります。zipコマンド+シェルの機能でもファイルを選定できますが、まず練習としてlsコマンドを使って目的のファイルを表示してみましょう。
 練習用としてデスクトップに怪しいディレクトリを用意しておきます。今回はrainbowというディレクトリを作成し、その中に画像ファイルを入れてあります。

 ここでは、このデスクトップ上にあるrainbowディレクトリをカレントディレクトリとします。カレントディレクトリにするにはcd ~/Desktop/rainbowと入力します。

 これで準備はOKです。まず、lsとだけ入力します。するとファイル名の一覧が表示されます。単純にlsとするとドットで始まるファイル以外が表示されます。

ls

ここで、index.jpgファイルだけ表示してみます。lsの後に半角空白を入れてindex.jpgと入力します。

ls index.jpg

これだとファイル名しか表示されませんので、ファイルの詳細も表示したい場合はlオプションを指定します。オプションを指定する場合は-の後にオプションとなる英文字を指定するのが定番です(他のコマンドも同様です)。

ls -l index.jpg

ただ、1つだけファイルを表示しても、あまり使い道がないかもしれません。やはり、特定の条件を満たすファイル名だけを表示するというのが多い用途でしょう。 ということで拡張子がjpgだけのものを表示してみます。この場合、lsの後に*.jpgを書きます。はワイルドカードで任意の文字列にマッチします。``.jpgだと拡張子がjpgの全てのファイルが対象になります。

ls *.jpg

さらにlオプションを指定すると拡張子がjpgのファイルの詳細が表示されます。

ls -l *.jpg

拡張子がjpgのファイルは表示されましたが、同じ画像形式のJPEGでも拡張子がjpegのファイルは表示されません。やはり、同じ画像形式ならまとめて表示してほしいところです。まあ、同じ画像形式なのに複数の拡張子があるのは何ともですが、ここらへんは拡張子が三文字しか使えないOSが普及していたからで過去のしがらみと言ったところです。他にもtifとtiffなど探せばありそうです。

それはさておき、異なる拡張子のファイルを表示するにはシェルの機能を利用します。なお、ここで使用するシェルはbash 3以上もしくはzshとします。PowerShellの場合、以下の説明のような{ }による指定はエラーになります。

拡張子がjpg、jpegのファイルを表示するには{ }を使います。{ }の中に表示したい拡張子を,で区切って書きます。 以下のように指定します。その際、{}の前後に空白を入れたり,の前後にも空白を入れたりしないでください。

ls *.{jpg,jpeg}

ファイルの詳細を表示したい場合はlオプションを指定します。

ls -l *.{jpg,jpeg}

複数の拡張子が指定できるので、JPEG形式以外のファイルもまとめて表示できます。

ls -l *.{jpg,png}

複数の拡張子ではなくファイル名に条件をつけることもできます。indで始まるファイルだけを表示するには以下のように*を使います。

ls ind*.*

ここまではカレントディレクトリの内容を表示しましたが、lsコマンドは表示するディレクトリを指定することもできます。cd ~として一旦ホームディレクトリに戻ります。

lsの後に表示したいディレクトリのパスを指定します。以下のように指定するとデスクトップ上にあるrainbowディレクトリの内容が表示されます。

ls ~/Desktop/rainbow

lオプションを指定する場合は以下のようにします。

ls -l ~/Desktop/rainbow

lsコマンドには多数のオプションがあります。また、*以外にも指定できるワイルドカードもあります。 が、今回はZIP圧縮するのが目的なので、lsコマンドに関してはこのくらいにしておきます。

ZIP圧縮する

 ZIP圧縮する前にcd ~/Desktop/rainbowとしてカレントディレクトリをrainbowディレクトリに移しておきます。ZIP圧縮する対象はrainbowディレクトリ内にあるファイルです。
 ZIP圧縮するにはzipコマンドを使います。zipの後に圧縮後のファイル名(ファイルパス)、つまりniji.zipといった拡張子がzipのファイル名を指定します。その後に圧縮するディレクトリ名を指定します。
 以下のようにするとデスクトップ上にあるrainbowディレクトリが丸ごとZIP圧縮されます。ZIP圧縮されたファイルはデスクトップに表示されます。

zip ~/Desktop/niji.zip *

ちゃんと圧縮されているかどうか確認してみましょう。とりあえず確認するだけなのでコマンド入力でなくFinder, ExplorerなどのGUIを利用すればよいでしょう。 解凍すると期待どおりの結果になっているのがわかります。

このZIPファイルはrainbowディレクトリ内の全てのファイルを圧縮しました。でも、PNG画像だけ圧縮したい、つまり特定の条件を満たしたファイルだけ圧縮したいこともあります。怪しいファイルとそうでないファイルをまぜこぜにしておけば何かあってもバレにくいというものです(?)

PNG画像だけを圧縮したい場合は以下のようにします。lsコマンドで特定の拡張子を持つファイルを表示する際に指定した方法と同じです。

zip ~/Desktop/niji.zip *.png

解凍してPNG画像だけ圧縮されているか確認してみます。PNG画像だけZIP圧縮されていてバッチリです。

JPEG画像の場合など拡張子が複数ある場合はlsコマンドで複数の拡張子を指定した方法を使います。

zip ~/Desktop/niji.zip *.{jpg,jpeg}

ZIPファイルを解凍して確認すると拡張子がjpgとjpegのファイルだけが圧縮されたことが確認できます。

パイプ(|)を使ってZIP圧縮する

ところで、zipコマンドでも圧縮するファイルを選定できるなら、なぜ最初にlsコマンドの解説をしたのか?と思う人もいるかもしれません。これはUNIXのパイプを利用するためです。パイプを利用すると直前のコマンドからの結果を受け取る事ができます。これを利用すると今日だけ変更されたファイルだけを選定して圧縮することができたりします。つまり、応用範囲が格段に広がるわけです。

ということで、今度はパイプを使ってファイルを圧縮してみます。lsコマンドで選定したPNG形式のファイルを|記号でzipコマンドに流し込みます。ここで注意しないといけないのがzipコマンドのオプションです。標準入力からのファイルを圧縮する場合、-@をつけないといけません。この指定がないと「zip error: Nothing to do!」のようにエラーとなり動作しません。

ls *.png | zip ~/Desktop/niji.zip -@

パイプを利用すると規則性のないファイル名をいくつか指定することもできます。例えば圧縮したいファイル名をテキストファイルに書いておきます。なお、このファイルはデスクトップにlist.txtという名前で保存しておきます。

これをcatと|を使ってzipコマンドに渡します。

cat ~/Desktop/list.txt | zip ~/Desktop/niji.zip -@

ZIPファイルを解凍するとlist.txtに指定したファイルだけが圧縮された事がわかります。

他にもfindコマンドなどと組み合わせると、より高度な圧縮処理を行うことができます。が、これはまたの機会に。

圧縮率を指定する

 画像ファイルなどがたくさんあると圧縮してもディスクの容量を圧迫してしまう事があります。容量の少ないSSDやDVDやBluRayにデータを保管する場合にはより小さいファイルサイズになると助かります。また、ネットワークにおいても流れるデータサイズが小さい方が良いでしょう。
 zipコマンドでは10段階で圧縮率を指定できます。オプションで-0から-9まで指定できます。-0だと全く圧縮しません。-9だと最高の圧縮率になります。無指定の場合は-6と同じになります。
 せっかくなので無圧縮(-0)、標準(-6)、最高圧縮(-9)でデータサイズを比較してみます。

・標準圧縮

zip ~/Desktop/niji.zip *

・非圧縮

zip -0 ~/Desktop/niji.zip *

・最高圧縮

zip -9 ~/Desktop/niji.zip *

まとめると、こんな結果になります。ファイル内容にもよりますが、最高圧縮にしてもあまりサイズが小さくならないこともあります。ここらへんは、まあ仕方ないこともありますが、マシンパワーがあるなら最高圧縮指定してもよいかもしれません。

 非圧縮 8496567
標準圧縮 7931851
最高圧縮 7931612

ZIPファイルを解凍する

 今度はZIPファイルを解凍してみます。これはunzipコマンドを使います。ここでは解凍先のディレクトリを作成しておき、そこに解凍したファイルを展開することにします。展開先のディレクトリはデスクトップにimagesとして用意します。

解凍するZIPファイルですが、先ほど圧縮したniji.zipの場合、以下のように指定します。

unzip ~/Desktop/niji.zip -d ~/Desktop/images

コマンドを実行したら、デスクトップのimagesディレクトリの内容を確認します。ちゃんと解凍されているのがわかります。

 そういえば書き忘れていましたがディレクトリ内にディレクトリがある場合は、ここまでのzipコマンドを入力しても期待通りに動作しません。圧縮されたZIPファイルを解凍してもサブディレクトリの内容は空っぽです。

ディレクトリ内のファイルも圧縮対象にするにはオプションにrを指定する必要があります。つまり以下のようにすればサブディレクトリまで圧縮されます。

zip -r ~/Desktop/niji.zip *

解凍すると期待通りの結果になっているのが確認できます。

zipコマンドは結構たくさんのオプションがありますが、まあ基本的なオプションだけでも十分使えるのではないでしょうか。

著者 仲村次郎
いろいろな事に手を出してみたものの結局身につかず、とりあえず目的の事ができればいいんじゃないかみたいな感じで生きております。