ファイルの圧縮についてまとめ

# はじめに

普段の業務ではあまり気にすることなく「いつも使う圧縮形式」で圧縮することが多いでしょうが、大容量を圧縮しなければならない場合やファイル容量を極力小さくしたい場合にたくさんある圧縮形式のどれを選ぶか迷うことがあります。そんなときに迷わず選択する手助けになれば幸いです。

# 圧縮形式の種類

## zip
普及率が高く、Win⇔Mac間や外国とのやり取りでも使いやすい。
パスワード設定や分割圧縮も可能。
圧縮率はあまり高くなく、4GBを越えるファイルや圧縮後に2GBを越えるファイルは圧縮できない。この場合、ファイルが破損してしまうが、見た目は圧縮できてしまうので注意が必要。
Macの標準機能でzip圧縮するとWinで文字化けするので注意。
Linuxでは標準では入っていないのでインストールする必要がある。

## rar
ヨーロッパで普及しているファイル圧縮形式。zipやlzhよりも圧縮率が高い。画像や動画の圧縮に向いている。圧縮には時間がかかる。
パスワード設定や分割圧縮も可能。
ダメージに強い。ハミング符号を付与することで、圧縮ファイルの破損をある程度修復できる。
Win、Mac、共に解凍には専用のソフトが必要。

## 7z（7zip）
ZIPに比べてかなり圧縮率が高い。しかも高速。オープンソース。
文字体系の違うファイルを混在させることもできる。
16 EB (16,000,000,000 GB) までのファイルを圧縮可能。
AES暗号が使えて暗号強度が高いが、相手のリテラシーが低いと手間がかかる。
ゲームなど大容量のファイルのやり取りに使われることが多い。

## gz（gzip）
Linux系の圧縮形式。標準的な圧縮方式。zipと同程度。拡張子は (tar).gz。
.tar.gz は .tgz になる場合もある。

## bzip
特許侵害のために配布が中止された高圧縮形式。

## bzip2
Linux系の圧縮形式。強力な圧縮方式。オープンソース。
バックアップとしてはこれが一般的。拡張子は (tar).bz2。

## lzh（LHA）
日本人が考案したアルゴリズムで、国内での普及率が高い。圧縮・解凍スピードの速さが特徴。
Winユーザーはソフトが無くても解凍できるが、Macユーザーは専用ソフトが必要になる。
現在はあまり使われなくなった。

## cab
マイクロソフトが開発したものでWindows標準のインストーラーで採用されている。

## sit
Mac OS 9 までの圧縮形式。現在はほとんど使われていない。

## 各圧縮形式の使いどころ

相手の環境を気にせずファイルのやり取りをするならzip形式がよい。

圧縮率を求めるなら環境によって使い分ける。
Winならcabか7z、Linuxならbz2。Macは残念ながらzip。

ちなみに、Linux系でよく見るtarは圧縮機能ではない。複数のフォルダ・ファイルを一つのファイルにまとめる単なるアーカイブ機能。


# 圧縮率の比較


情報元1
http://www.emit.jp/dgca/cmptest.html
情報元2
https://forest.watch.impress.co.jp/article/1998/11/16/compress.html

※数値が低い方が圧縮率が高い。

## テキストファイル（html）の圧縮率比較

|圧縮形式|圧縮率|
|:---|---:|
|bz2 | 25.4% |
|7z  | 27.7% |
|cab | 27.9% |
|rar | 29.9% |
|zip | 41.2% |
|lzh | 44.2% |

## 画像（bmp）の圧縮率比較

|圧縮形式|圧縮率|
|:---|---:|
|rar | 48.6% |
|7z  | 51.7% |
|bz2 | 53.9% |
|cab | 58.7% |
|zip | 62.6% |
|lzh | 63.6% |

rar、7z、bz2 の３つの形式がほぼ互角。rarが画像に強く、bz2がテキストに強い。
特にテキストの圧縮率の差が大きい。

## バイナリ（exe）の圧縮率比較

|圧縮形式|圧縮率|
|:---|---:|
|cab | 36.4% |
|rar | 41.8% |
|bz2 | 42.7% |
|lzh | 44.4% |
|zip | 45.0% |
|sit | 46.3% |

## バイナリ（exe）の圧縮速度比較

|圧縮形式|圧縮速度|
|:---|---:|
|sit | 69s |
|zip | 96s |
|bz2 | 100s |
|lzh | 119s |
|cab | 246s |
|rar | 1,075s |

## テキストファイル（txt）の圧縮率比較

|圧縮形式|圧縮率|
|:---|---:|
|cab | 40.0% |
|rar | 40.7% |
|bz2 | 40.7% |
|lzh | 44.0% |
|zip | 44.6% |
|sit | 45.8% |

## テキストファイル（txt）の圧縮速度比較

|圧縮形式|圧縮速度|
|:---|---:|
|zip | 23s |
|sit | 33s |
|lzh | 41s |
|bz2 | 72s |
|cab | 113s |
|rar | 352s |

Windowsファイルはマイクロソフト製のcabが優秀。
rarは圧縮率は高いが時間がかかる。


# Linuxの圧縮・解凍コマンド

## gzipコマンド

### 書式

```sh
# gzip [オプション] [ファイル名]
```

### オプション

|オプション|内容|
|:---|:---|
|-a | 圧縮時に改行コードを「CR LF」から「LF」に、展開時に「LF」から「CR LF」に変換する。|
|-c | 圧縮結果を標準出力に表示する。|
|-d | 圧縮されたファイルを展開する。gunzipコマンドと同等。|
|-f | ファイルが既に存在する場合は上書きする。|
|-l | 圧縮されたファイルの情報（サイズ、圧縮率、ファイル名）を表示する。|
|-r | 指定したディレクトリ内のファイルを圧縮する。|

### 圧縮

#### 単一ファイルを圧縮する

```sh
# gzip file.txt
```
⇒ file.txt.gz
※このとき、元のファイルは無くなる。

#### 複数のファイルを一度に圧縮

```sh
# gzip file1.txt file2.txt
```
⇒ file1.txt.gz, file2.txt.gz
※それぞれ単一ファイルで圧縮される。元のファイルは無くなる。

#### 圧縮前のファイルを残して圧縮したい場合

```sh
# gzip -c file.txt > file.txt.gz
```
※標準出力を通して圧縮する。

#### ディレクトリ内の複数ファイルをまとめて圧縮

ディレクトリ内のファイルをまとめて圧縮する場合はtarでアーカイブしてから圧縮する。
tar の z オプションを使えばgzip形式で圧縮してくれる。

```sh
# tar -cvzf dir.tar.gz dir
```
⇒ dir.tar.gz, dir
※ディレクトリは残る。

以下は上と同等。

```sh
# tar -cf dir.tar dir; gzip dir.tar
```
⇒ dir.tar.gz, dir

オプション -r はディレクトリを圧縮するのではなく、ディレクトリ内のファイルを圧縮する。
例えば以下のようなディレクトリ構造の場合は

    dir/
      file.txt
      dir2/
        file2.txt

オプション -r で圧縮すると以下のようなファイルができる。

```sh
# gzip -r dir
```
⇒

    dir/
      file.txt.gz
      dir2/
        file2.txt.gz


### 解凍

#### 単一ファイルの解凍

```sh
# gzip -d file.txt.gz
```
⇒ file.txt
※このとき、file.txt.gzは無くなる。

#### 解凍前のファイルを残して解凍したい場合

```sh
# gzip -dc file.txt.gz > file.txt
```
※標準出力を通して解凍する。

#### アーカイブされた圧縮ファイルを解凍

```sh
# tar xvzf dir.tar.gz
```
⇒ dir/

#### ディレクトリ内に含まれる圧縮ファイルを解凍する

例えば以下のようなディレクトリ構造で圧縮ファイルがある場合。

    dir/
      file.txt.gz
      dir2/
        file2.txt.gz

オプション -r で解凍すると以下のようなファイルができる。

```sh
# gzip -dr dir
```
    dir/
      file.txt
      dir2/
        file2.txt


## bzip2コマンド

### 書式

```sh
# bzip2 [オプション] ファイル名
```

### オプション

|オプション|内容|
|:---|:---|
|-c | 圧縮結果を標準出力に表示する。|
|-d | 圧縮されたファイルを展開する。bunzip2コマンドと同等。|
|-f | ファイルが既に存在する場合は上書きする。|
|-t | 圧縮テストを実行する。圧縮は行われない。|
|-v | 圧縮率を表示する。|

### 圧縮

#### 単一ファイルを圧縮する

```sh
# bzip2 file.txt
```
⇒ file.txt.bz2
※このとき、元のファイルは無くなる。

#### 複数のファイルを一度に圧縮

```sh
# bzip2 file1.txt file2.txt
```
⇒ file1.txt.bz2, file2.txt.bz2
※それぞれ単一ファイルで圧縮される。元のファイルは無くなる。

#### 圧縮前のファイルを残して圧縮したい場合

```sh
# bzip2 file.txt -c > file.txt.bz2
```
⇒ file.txt.bz2, file.txt

#### ディレクトリ内の複数ファイルをまとめて圧縮

```sh
# tar cvjf dir.tar.bz2 dir
```



⇒ dir.tar.bz2, dir
※ディレクトリは残る。

以下は上と同等。

```sh
# tar -cf dir.tar dir; bzip2 dir.tar
```
⇒ dir.tar.bz2, dir

### 解凍

#### 単一ファイルの解凍

```sh
# bzip2 -d file.txt.bz2
```
⇒ file.txt
※このとき、file.txt.bz2は無くなる。

#### 解凍前のファイルを残して解凍したい場合

```sh
# bzip2 -dc file.txt.bz2 > file.txt
```
※標準出力を通して解凍する。

#### アーカイブされた圧縮ファイルを解凍

```sh
# tar xvjf dir.tar.bz2
```
⇒ dir/


## zipコマンド

Linuxでは標準では入っていないのでインストールする。
gzipやbzip2とは書式も挙動も若干違うので注意。
このコマンドは圧縮のみ。解凍は unzip や gunzip を使う。

### 書式

```sh
# zip [オプション] アーカイブ名 [対象ファイル]
```
※アーカイブ名に拡張子を指定せずにコマンドを実行すると、自動的に拡張子 .zip が付く。

### オプション


|オプション|内容|
|:---|:---|
|-e | 圧縮ファイルにパスワードを設定する。|
|-r | ディレクトリを再帰的に圧縮する。|
|-u | 圧縮されているファイル内のファイルを更新する。|
|-z | アーカイブにコメントを追加する。|
|-@ | 対話形式で圧縮するファイルを指定する。|
|-x | 除外するファイルを指定する。|
|-i | 対象とするファイルを指定する。|
|-m | 元のファイルを削除する。|
|-T | 圧縮テストを実行する。圧縮は行われない。※大文字なので注意。小文字(t)のオプションもある。|

### 圧縮

#### 単一ファイルを圧縮する

```sh
# zip archive file.txt
```
⇒ archive.zip, file.txt
※元のファイルは残る。

#### 複数のファイルを一度に圧縮

```sh
# zip archive file1.txt file2.txt
```
⇒ archive.zip, file1.txt, file2.txt
※元のファイルは残る。

#### 圧縮後、元のファイルを削除する

```sh
# zip -m archive file.txt
```
⇒ archive.zip

#### ディレクトリ内の複数ファイルをまとめて圧縮

```sh
# zip archive -r dir
```
⇒ archive.zip, dir
※ディレクトリは残る。

#### 圧縮ファイルにパスワードを設定する

```sh
# zip -e archive -r dir
Enter password:
Verify password:
```
⇒ archive.zip, dir

#### .txtファイルのみ圧縮する

```sh
# zip archive *.txt
```

#### ディレクトリ内の.txtファイルのみ圧縮する

```sh
# zip archive -r dir -i "*.txt"
```

#### .zipファイルを除外する

```sh
# zip -r archive dir -x "*.zip"
```


## unzipコマンド

### 書式

```sh
# unzip [オプション] ZIPファイル名 [対象ファイル]
```

### オプション


|オプション|内容|
|:---|:---|
|-c | 標準出力に展開結果を表示する。|
|-d | 指定ディレクトリにファイルを展開する。|
|-l | アーカイブの中身を表示する。|
|-p | 展開結果をパイプ（|）に渡す。|
|-t | 展開テストを実行する。展開は行われない。|
|-v | アーカイブの中身とその詳細を表示する。|
|-z | アーカイブのコメントを表示する。|
|-o | 常に上書きする。|
|-n | 上書きしない。|
|-u | 新しいファイルのみ上書きする。|


### 解凍

#### 単一ファイルの解凍

```sh
# unzip archive.zip
```
⇒ archive.zip, file.txt
※元のファイルは残る。

#### アーカイブされた圧縮ファイルを解凍

```sh
# unzip archive.zip
```
⇒ archive.zip, dir/
※元のファイルは残る。

#### ディレクトリを指定してアーカイブされた圧縮ファイルを解凍

```sh
# unzip archive.zip -d dir
```
⇒ archive.zip, dir/dir/
※指定ディレクトリ内に展開される。

#### .txtファイルのみ展開する

```sh
# unzip archive.zip "*.txt"
```

#### サブディレクトリを作成せずにファイルだけを取り出す

```sh
# unzip -j archive.zip "*.txt"
```

## tarコマンド

圧縮機能ではないが圧縮にはかかせないので記載。

### 書式

#### アーカイブ時

```sh
# tar [オプション] アーカイブ名 対象ファイル
```

#### 展開時

```sh
# tar [オプション] アーカイブ名
```

### オプション

#### 共通オプション

|オプション|内容|
|:---|:---|
|-f | アーカイブファイル名を指定する。|
|-v | 処理したファイルの一覧を詳細に表示する。|
|-w | 処理するごとに確認を求める。|

#### アーカイブ時のオプション

|オプション|内容|
|:---|:---|
|-c | 新しいアーカイブを作成する。|
|-r | アーカイブの最後にファイルを追加する。|
|-u | アーカイブのファイルを更新する。アーカイブ内の同名ファイルより新しいものだけを追加する。|
|-A | tarアーカイブされたファイルを追加する。|
|--delete | アーカイブファイル内から指定ファイルを削除する。|
|-V | アーカイブにボリューム名を設定する。|
|-C | アーカイブ元のファイルのディレクトリを指定する。|
|--totals | 書き込まれたサイズを表示する。|
|-W | アーカイブを書き出した後に検証する。|

#### 圧縮オプション

|オプション|内容|
|:---|:---|
|-z | gzip形式で圧縮する。|
|-j | bzip2形式で圧縮する。|

#### 展開オプション

|オプション|内容|
|:---|:---|
|-x | アーカイブからファイルを展開する。|
|-k | ファイルが存在する場合は上書きしない。|
|-m | 展開したファイルの更新時刻を現在時刻とする。|
|-O | 展開したファイルを標準出力に書き出す。|
|-C | 展開先のディレクトリを指定する。|
|--strip-components | 展開するディレクトリを指定した階層だけスキップする。|

#### 確認用オプション

|オプション|内容|
|:---|:---|
|-t | アーカイブの内容の一覧を表示する。|
|-d | アーカイブ元とアーカイブファイルの違いをチェックする。|

### アーカイブ

#### 単一ファイルをアーカイブする

```sh
# tar cvf file.tar file.txt
```
⇒ file.tar, file.txt
※元のファイルは残る。

#### 複数のファイルをアーカイブする

複数の対象ファイルは半角スペースで区切って指定する。

```sh
# tar cvf file.tar file1.txt file2.txt
```
⇒ file.tar, file1.txt, file2.txt
※元のファイルは残る。

#### ディレクトリをまとめてアーカイブする

```sh
# tar cvf dir.tar dir
```
⇒ dir.tar, dir
※ディレクトリは残る。

### 圧縮（gzip形式）

#### 単一ファイルを圧縮する

```sh
# tar cvzf file.tar.gz file.txt
```
⇒ file.tar.gz, file.txt
※元のファイルは残る。

#### 複数のファイルを圧縮する

複数の対象ファイルは半角スペースで区切って指定する。

```sh
# tar cvzf file.tar.gz file1.txt file2.txt
```
⇒ file.tar.gz, file1.txt, file2.txt
※元のファイルは残る。

#### ディレクトリをまとめてアーカイブする

```sh
# tar cvzf dir.tar.gz dir
```
⇒ dir.tar.gz, dir
※ディレクトリは残る。

### 圧縮（bzip2形式）

#### 単一ファイルを圧縮する

```sh
# tar cvjf file.tar.bz2 file.txt
```
⇒ file.tar.bz2, file.txt
※元のファイルは残る。

#### 複数のファイルを圧縮する

複数の対象ファイルは半角スペースで区切って指定する。

```sh
# tar cvjf file.tar.bz2 file1.txt file2.txt
```
⇒ file.tar.bz2, file1.txt, file2.txt
※元のファイルは残る。

#### ディレクトリをまとめてアーカイブする

```sh
# tar cvjf dir.tar.bz2 dir
```
⇒ dir.tar.bz2, dir
※ディレクトリは残る。

### 解凍、展開

#### アーカイブファイルを展開

```sh
# tar xvf archive.tar
```
⇒ dir/, archive.tar
※アーカイブファイルは残る。

#### gzip形式のファイルを解凍、展開

```sh
# tar xvzf archive.tar.gz
```
⇒ dir/, archive.tar.gz
※gzip形式のファイルは残る。

#### bzip2形式のファイルを解凍、展開

```sh
# tar xvjf archive.tar.bz2
```
⇒ dir/, archive.tar.bz2
※bzip2形式のファイルは残る。

#### ディレクトリを指定してアーカイブされた圧縮ファイルを解凍

```sh
# tar xvjf archive.tar.bz2 -C dir
```
⇒ dir/dir/, archive.tar.bz2
※指定ディレクトリ内に展開される。

#### 特定ファイルのみ展開する

```sh
# tar xvf archive.tar ./dir/file.txt
```
⇒ dir/file.txt, archive.tar
※途中のディレクトリも作成される。

#### ワイルドカードで指定したファイルのみ展開する

`tar` はワイルドカードの引数に対応していない。
`tar tf` で一覧を表示してから `grep` で絞り込む。

```sh
# tar xvf archive.tar $(tar tf archive.tar | grep '*.txt')
```

#### ２階層目以降を展開する

```sh
# tar xvf archive.tar --strip-components 1
```
⇒ file.txt, archive.tar
※１階層目のディレクトリは作成されない。