zipコマンドの微妙な違いを知っておきたい

この記事はだいぶ前に書かれたものなので情報が古いかもしれません
ジッパー

この記事を三行にまとめると

フォルダごと圧縮する
フォルダの中だけ圧縮する
macでzipファイルを作るときの話
例えば以下のようなフォルダとファイルがあるとします。

/dir
  └ /images
      ├ image1.png
      ├ image2.png
      └ image3.png

3枚の画像がimagesというフォルダに入っている状態ですね。

このimagesの中身をzipコマンドを使って「image.zip」というファイル名で圧縮したい場合、パターンとしては主に以下の3つがあると思います。

$ zip images.zip images/*
$ zip -r images.zip images
$ zip -j images.zip images/*

どれを使ってもほぼ一緒なんですけど、フォルダごと圧縮するかフォルダの中だけを圧縮するかという微妙な違いがあります。

どういうことか順番に見ていきましょう。



フォルダごと圧縮する

「zip images.zip images/*」のようにワイルドカードを使うとフォルダの中にあるファイルをまとめて圧縮することができます。「images/*」とした場合はimagesフォルダの中の全ファイルを圧縮ということですね。「images/*.png」とかにするとpngファイルだけをまとめて圧縮できたりする。

「zip -r images.zip images」のようにrオプションを使った場合はフォルダ名を指定するだけでその中のファイルを再帰的に圧縮してくれるので、ワイルドカードなどは不要です。

上記の2パターンはフォルダごと圧縮するやり方です。実際に圧縮してみるとzipファイルの中身はこんな風になります。

フォルダごと圧縮

imagesフォルダがあってその中に3つのpngファイルがありますね。まあ特に問題はないと思います。

ちなみにこれはBetterZipと言ってzipファイルの解凍ソフトの一つなのですが、解凍せずにzipファイルの中身が見れたりするなかなか便利なやつです。解凍しなくても中身が確認できるって結構すごくない? スカートが風でめくれなくてもその中が見えたらとんでもないことじゃん? それを可能にするレベルのツールですよ、こいつは。

ここでこのzipファイルをunzipコマンドで解凍すればファイル構成はこのような状態になります。

$ unzip images.zip

/dir
  ├ images.zip
  └ /images
      ├ image1.png
      ├ image2.png
      └ image3.png

zipファイルが残ったままという以外は圧縮前の状態と一緒ですね。

基本的にはどちらのコマンドで作成しても問題ないですが、フォルダの中にさらにフォルダがある場合はrオプションを使った方が良いです。

/dir
  └ /images
      ├ image1.png
      ├ image2.png
      ├ image3.png
      └ /jpg
          ├ image1.jpg
          └ image2.jpg

例えばこんな感じの中身に対してワイルドカードで圧縮をすると、jpgフォルダの中身が圧縮されずに空の状態になってしまいます。フォルダの中にフォルダがある時はrオプションで再起的に圧縮する必要があります。



フォルダの中だけ圧縮する

続いて「zip -j images.zip images/*」のようにjオプションを使った場合。jオプションはディレクトリ構造を無視するというオプションです。

結果はこうなります。

フォルダの中だけ圧縮

さっきと違い、zipファイルの中にimagesフォルダがありませんね。これをunzipで解凍するとこうなります。

$ unzip images.zip

/dir
  ├ images.zip
  ├ image1.png
  ├ image2.png
  └ image3.png

imagesフォルダはなくなりzipファイルの同階層に3つのpng画像が並びます。でもunzipコマンドを使わずにzipファイルをダブルクリックで解凍した場合は、フォルダごと圧縮した場合と同様にimagesフォルダができてその中にpng画像が入ります。

「unzipを使わなきゃ結果は同じなんだったら気にしなくてよくない?」って思うかもしれませんが、何らかのウェブサービスでzipファイルをアップロードする仕組みがある場合に、zipファイルの中にフォルダがあるかないかによってエラーが出たり出なかったりすることがあります。

僕が先日実際に目にした具体例で言うと、Microsoft Teamsにカスタムアプリとしてzipファイルをアップロードする仕組みがあるんですけど、そこにフォルダごと圧縮したzipファイルを上げるとエラーになってしまいます。たぶんunzipしたら最初の階層がフォルダになっちゃって、結果として必要なファイルが入っていると認識できなくてエラーになっちゃうんじゃないかと思います。

そういう時はjオプションを使ってフォルダの中だけのzipファイルを作るようにした方が良いでしょう。



macでzipファイルを作るときの話

macでファイルを圧縮すると「__MACOSX」などの余計なファイルが一緒に入ってしまうことがあります。先ほどのTeamsの話もそうなんですが、不要なファイルが入っていると何らかの操作の際に意図せぬエラーが出てしまうことがあります。

でもzipコマンドを使ってフォルダを圧縮すれば__MACOSXフォルダは作成されないので、こいつができてほしくないって時はターミナルなどを起動してzipコマンドで圧縮すればオッケーです。






今じゃクラウドでファイルを共有するのも当たり前になってきてるから、圧縮しないでフォルダごとクラウドに突っ込んじゃえば完了ってことも多々あると思うんですけど、それでもzipの出番が減ったなあという印象があまりない気がします。まあ、メールにパスワードつきのzipファイルを添付して送る機会はほとんどなくなりましたけどね。

以前は仕事でクライアントさんにzipファイルを送らなきゃいけない時、先方さんからはほぼ必ずと言って良いほどパスワードつきのzipファイルが送られてくるから、そのたびに「こっちもパスワードかけなきゃいけないよなあ……どうやるんだっけ」と毎回調べるという非効率なことをやっておりました。

ちなみに「zipcloak」というコマンドを使うと作成したzipファイルにパスワードをかけられます。

zipcloak images.zip
 もしかしたら何か関連しているかも? 
 質問や感想などお気軽にコメントしてください