32blogby StudioMitsu

tar・gzip・zipコマンド実践ガイド|圧縮と展開を完全理解

tar・gzip・zip・zstdの実践的な使い方をコード例付きで解説。圧縮アルゴリズムの速度・圧縮率比較からバックアップ自動化パターンまで網羅。

19 min read
CLILinuxbashtarcompressionscripting
目次

tar はファイルをひとつにまとめるアーカイブツール。gzipbzip2xzzstd はそのアーカイブ(あるいは単体のファイル)を圧縮して容量を減らすツール。zip はアーカイブと圧縮を一発でやるツール。この違いを理解しておくと、「なんか展開できない」「圧縮に時間かかりすぎ」「相手がファイル開けない」みたいなトラブルが一気に減る。

結論から言うと、tar czf archive.tar.gz dir/ で gzip 圧縮アーカイブを作成、tar xf archive.tar.gz で展開。速度と圧縮率のバランスを求めるなら zstd に切り替えて tar --zstd -cf archive.tar.zst dir/。zip は Windows/macOS ユーザーとファイル共有するときだけ使う。

アーカイブと圧縮は別物 — まずここを押さえる

Linux を使い始めたとき、僕はこの区別がついていなくて何度かハマった。はっきり言うと、アーカイブ圧縮 はまったく別の操作だ。

アーカイブ は複数のファイルやディレクトリをひとつにまとめる操作。tar(tape archive の略)がやるのはこれだけ。できあがる .tar ファイル(通称「tarball」)は、元ファイルの合計サイズとほぼ同じ。容量は減らない。

圧縮 はデータサイズをアルゴリズムで縮小する操作。gzipbzip2xzzstd はそれぞれ異なる圧縮アルゴリズムを実装していて、入力は1ファイルのみ。

Unix の流儀では、この2つを組み合わせる。tar でまとめて1ストリームにしてから、圧縮ツールで縮小する:

bash
# 2段階でやる方法(実際にはほぼ使わない)
tar cf project.tar project/
gzip project.tar
# 結果: project.tar.gz

# 1コマンドでやる方法(こっちが普通)
tar czf project.tar.gz project/

なぜこの違いが重要か? zip はアプローチが根本的に異なる。zip はファイルを個別に圧縮してからまとめる。一方、tar.gz は全ファイルをひとつのストリームとしてまとめてから圧縮する。ファイル間の類似パターンを利用できるぶん、tar.gz のほうが一般的に 5〜15% 小さくなる。特にソースコードのように似たファイルが大量にあるケースで差が出る。

tar 方式:  [file1][file2][file3] → tar → [1ストリーム] → gzip → .tar.gz
zip 方式:  [file1→gz][file2→gz][file3→gz] → まとめる → .zip

逆に言えば、.zip なら個別ファイルを全体を展開せずに取り出せるけど、.tar.gz はストリーム全体を展開しないといけない。この特性を知ったうえで使い分けると、作業が効率的になる。

tar の基本操作 — 作成・展開・一覧表示

毎日使う主要フラグはこれだけ:

フラグ意味
c新規アーカイブを create
xアーカイブから extract
t中身を一覧表示(list
fファイル名を指定(ほぼ必須)
v処理中のファイルを表示(verbose)
zgzip で圧縮/展開
jbjip2 で圧縮/展開
Jxz で圧縮/展開(大文字の J

アーカイブの作成

bash
# 圧縮なしの tarball
tar cf backup.tar documents/

# gzip 圧縮
tar czf backup.tar.gz documents/

# xz 圧縮(最小サイズ・最も遅い)
tar cJf backup.tar.xz documents/

# zstd 圧縮(速い+高圧縮率)
tar --zstd -cf backup.tar.zst documents/

アーカイブの展開

GNU tar はバージョン 1.15 以降、圧縮形式を自動検出する。展開時に -z-j を指定する必要はない:

bash
# どの圧縮形式でも自動検出して展開
tar xf backup.tar.gz
tar xf backup.tar.xz
tar xf backup.tar.zst

# 展開先ディレクトリを指定
tar xf backup.tar.gz -C /opt/restore/

# 特定のファイルだけ展開
tar xf backup.tar.gz documents/report.pdf

中身の確認

展開する前に中身を確認する癖をつけよう。ネットから落としてきた tarball がサブディレクトリなしでカレントに直接展開される、いわゆる「tarbomb」に何度か遭遇した経験がある:

bash
# ファイル一覧を表示
tar tf backup.tar.gz

# 詳細情報(パーミッション、サイズ、日付)
tar tvf backup.tar.gz

# トップレベルにディレクトリがあるか確認
tar tf backup.tar.gz | head -5

除外パターン

プロジェクトのバックアップでは除外設定が大事。Node.js プロジェクトで node_modules が入った 800MB の tarball を作ってしまったことがある(プロジェクト本体は 50KB だった):

bash
# 特定のディレクトリを除外
tar czf 32blog-backup.tar.gz \
  --exclude='node_modules' \
  --exclude='.next' \
  --exclude='.git' \
  32blog/

# パターンで除外
tar czf source-only.tar.gz \
  --exclude='*.log' \
  --exclude='*.tmp' \
  project/

既存アーカイブへのファイル追加

非圧縮の .tar にはファイルを追加できるけど、圧縮済みアーカイブには追加できない:

bash
# 既存の tar にファイル追加
tar rf backup.tar newfile.txt

# 圧縮済みには追加できない
tar rf backup.tar.gz newfile.txt  # エラー!

圧縮アルゴリズムの選び方 — gzip / bzip2 / xz / zstd

それぞれ速度と圧縮率のトレードオフが異なる。

gzip — 万能の定番

GNU gzip は 30 年以上 Unix の標準圧縮ツールとして使われている。2025 年 2 月リリースのバージョン 1.14 では、x86-64 CPU で PCLMUL 命令を使った CRC 計算の高速化が入った。

bash
# 単体ファイルを圧縮(元ファイルは消える)
gzip access.log
# 結果: access.log.gz

# 元ファイルを残す
gzip -k access.log

# 展開
gunzip access.log.gz
# または
gzip -d access.log.gz

# 圧縮レベル(1=最速, 9=最小, デフォルト=6)
gzip -9 access.log

使いどころ: スクリプト、ログローテーション、互換性が最重要な場面。どんな Unix システムにも入っている。

bzip2 — 圧縮率は良いが遅い

bash
tar cjf archive.tar.bz2 project/

gzip より 10〜15% 良い圧縮率だけど、速度がかなり遅い。xz(圧縮率がさらに良い)と zstd(速度がさらに速い)に取って代わられつつある。.tar.bz2 を見かけることはあっても、新しく作る理由はあまりない。

xz — 最大圧縮

XZ Utils は一貫して最小のアーカイブを作る。Linux カーネルの tarball や Debian パッケージなど、多くのオープンソースプロジェクトが .tar.xz で配布している:

bash
# xz で圧縮
tar cJf archive.tar.xz project/

# マルチスレッド圧縮(xz はデフォルトでシングルスレッド)
tar -cf - project/ | xz -T0 > archive.tar.xz

# 展開
tar xf archive.tar.xz

使いどころ: ソフトウェア配布、ストレージコスト > 時間コストの長期保存。

zstd — モダンな最適解

Zstandard(zstd)は Facebook が開発した圧縮ツール。2025 年 2 月リリースのバージョン 1.5.7 では、デフォルトでマルチスレッド圧縮(最大 4 スレッド)が有効になった。

bash
# zstd 圧縮アーカイブを作成
tar --zstd -cf archive.tar.zst project/

# 単体 zstd 圧縮
zstd -T0 large-file.sql
# 結果: large-file.sql.zst

# レベル指定(デフォルト範囲 1-19、--ultra で 20-22)
zstd -19 large-file.sql
zstd --ultra -22 large-file.sql  # 最大圧縮

# 展開
zstd -d large-file.sql.zst
unzstd large-file.sql.zst

32blog のコンテンツディレクトリのバックアップを gzip から zstd に切り替えたら、圧縮時間が約 60% 短くなって、圧縮率もわずかに改善した。唯一のデメリットは、古いシステム(2019 年以前)に zstd が入っていない可能性があること。

使いどころ: 圧縮・展開の両方を自分で管理できる環境全般。バックアップ、CI/CD、データベースダンプ、コンテナイメージ。

zip と unzip — クロスプラットフォームの選択肢

zip は Windows・macOS・Linux のどれでもネイティブに扱える形式だ。tar + 圧縮ツールの組み合わせとは違い、アーカイブと圧縮を一発でやる:

bash
# zip アーカイブ作成
zip -r project.zip project/

# 圧縮レベル指定(0=無圧縮, 9=最大圧縮)
zip -r -9 project.zip project/

# パターンで除外
zip -r project.zip project/ -x "*.git*" "*/node_modules/*"

# 中身一覧
unzip -l project.zip

# 展開
unzip project.zip

# 展開先ディレクトリ指定
unzip project.zip -d /opt/restore/

# 特定ファイルだけ展開
unzip project.zip "project/config.json"

パスワード付きアーカイブ

bash
# 暗号化 zip を作成(パスワード入力を求められる)
zip -er sensitive.zip contracts/

# 展開(パスワード入力を求められる)
unzip sensitive.zip

tar.gz ではなく zip を使うべき場面

  • ターミナルを使わない Windows・macOS ユーザーとのファイル共有
  • Java の .jar / .war ファイル(実体は zip)
  • メール添付(zip は誰でも開ける)
  • 全体を展開せずに個別ファイルにアクセスしたいとき

それ以外 — バックアップ、デプロイ、データ保存 — は tar + 好みの圧縮ツールを使おう。

実践パターン — バックアップ・デプロイ・パイプライン

タイムスタンプ付きバックアップ

32blog のコンテンツディレクトリで実際に使っているパターン。タイムスタンプ付きなので上書きされない:

bash
#!/usr/bin/env bash
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
BACKUP_DIR="/backups"
SOURCE_DIR="/var/www/32blog"

tar --zstd -cf "${BACKUP_DIR}/32blog-${TIMESTAMP}.tar.zst" \
  --exclude='node_modules' \
  --exclude='.next' \
  --exclude='.git' \
  "${SOURCE_DIR}"

# 30日より古いバックアップを削除
find "${BACKUP_DIR}" -name "32blog-*.tar.zst" -mtime +30 -delete

echo "Backup created: 32blog-${TIMESTAMP}.tar.zst"

SSH 経由のリモート転送(中間ファイルなし)

tar を SSH にパイプして、中間ファイルを作らずにリモートサーバーへディレクトリ転送する。SSH のパターンは ssh・rsync ガイド でさらに詳しく扱っている:

bash
# ディレクトリをリモートサーバーにコピー
tar czf - project/ | ssh user@server "tar xzf - -C /opt/deploy/"

# リモートからローカルにコピー
ssh user@server "tar czf - /var/log/app/" | tar xzf - -C ./logs/

# プログレスバー付き(pv が必要)
tar cf - project/ | pv | ssh user@server "tar xf - -C /opt/deploy/"

大きなアーカイブの分割

サイズ制限がある環境(メール、USB、不安定なネットワーク)で大きなアーカイブを転送する場合:

bash
# 100MB ずつに分割
tar czf - large-project/ | split -b 100M - backup-part-

# 結合して展開
cat backup-part-* | tar xzf -

find との連携

tar を findxargs と組み合わせると、柔軟なワークフローが組める:

bash
# .tar.gz ファイルを全て見つけて展開
find /downloads -name "*.tar.gz" -exec tar xzf {} -C /opt/extracted/ \;

# 24時間以内に変更されたファイルだけアーカイブ
find project/ -mtime -1 -type f -print0 | \
  tar czf recent-changes.tar.gz --null -T -

# 特定の拡張子だけアーカイブ
find src/ -name "*.ts" -o -name "*.tsx" | \
  tar czf typescript-source.tar.gz -T -

tar の差分バックアップ

GNU tar はスナップショットファイルを使った差分バックアップに対応している。初回はフルバックアップ、2回目以降は変更分だけをバックアップする:

bash
# フルバックアップ(スナップショットファイルを作成)
tar --listed-incremental=snapshot.snar \
  -czf backup-full.tar.gz project/

# 差分バックアップ(前回以降の変更分のみ)
tar --listed-incremental=snapshot.snar \
  -czf backup-incr-$(date +%Y%m%d).tar.gz project/

# 復元: フルバックアップを先に、差分を順番に適用
tar --listed-incremental=/dev/null -xzf backup-full.tar.gz
tar --listed-incremental=/dev/null -xzf backup-incr-20260323.tar.gz

速度 vs 圧縮率 — ベンチマーク比較

32blog のソース(ソースコード・MDX コンテンツ・アセット合わせて約 180MB)で各アルゴリズムをベンチマークした結果:

アルゴリズムコマンドフラグ圧縮後サイズ圧縮速度展開速度
gzip -1tar czf(高速)約45MB非常に速い速い
gzip -6tar czf(デフォルト)約38MB速い速い
gzip -9tar czf(最大)約37MB普通速い
bzip2tar cjf約33MB遅い遅い
xz -6tar cJf約28MB非常に遅い普通
zstd -3tar --zstd(デフォルト)約36MB非常に速い非常に速い
zstd -19tar --zstd(高圧縮)約29MB遅い非常に速い
zip -6zip -r(デフォルト)約40MB速い速い

ポイント:

  • zstd デフォルト は gzip に近い圧縮率を 3〜5 倍速い速度で達成する
  • xz はサイズで勝つけど、大きなデータだと圧縮時間が体感で長い
  • zstd の展開 は圧縮レベルに関係なく常に最速
  • zip はファイル個別圧縮なので、圧縮率では常に負ける

普段使いなら zstd のデフォルト設定 が最良のオールラウンダー。何千回もダウンロードされるアーカイブには xz を使う(圧縮時間の投資が帯域幅で回収できる)。どんなシステムでも確実に動く互換性が要るなら gzip

FAQ

.tar.gz と .tgz の違いは?

同じ形式。.tgz は DOS や古い Windows が二重拡張子を扱えなかった時代の名残り。どちらを使っても tar は同じように処理する。

.tar.gz から特定のファイルだけ展開できる?

展開時にファイルパスを指定すればできる(tar xzf archive.tar.gz path/to/file)。ただし tar はそのファイルに到達するまでストリーム全体を展開する必要がある。本当のランダムアクセスが必要なら zip を使おう。

圧縮中の進捗を表示するには?

pv(pipe viewer)を tar と圧縮ツールの間に挟む:tar cf - bigdir/ | pv | gzip > archive.tar.gz。速度と残り時間付きのプログレスバーが表示される。

tar は 4GB 以上のファイルを扱える?

扱える。GNU tar は POSIX 拡張ヘッダを使うので、実質的なファイルサイズ制限はない。古い zip 実装(Zip64 以前)は 4GB 超のファイルを扱えなかった。大きなファイルには tar を使うべき理由のひとつ。

新しいプロジェクトでは gzip と zstd のどちらを使うべき?

圧縮と展開の両方を自分で管理できるなら zstd。速度も圧縮率も gzip より優れている。zstd が入っていない可能性があるシステム(2019 年以前のディストリ、組み込み、最小構成の Docker イメージ)との互換性が必要な場合だけ gzip にフォールバックする。

ディスクやパーティション全体を圧縮するには?

dd を圧縮ツールにパイプする:dd if=/dev/sda bs=4M | zstd -T0 > disk-image.zst。ファイルシステム単位のバックアップには、tar の --one-file-system のほうが安全:tar --one-file-system -czf root-backup.tar.gz /

アーカイブの破損を確認する方法は?

tar tzf archive.tar.gz > /dev/null を実行する。アーカイブ全体を読み込んで、破損があればエラーになる。gzip ファイル単体なら gzip -t file.gz、zstd なら zstd -t file.zst で整合性チェックができる。

-p フラグの意味は?

-p(preserve permissions)は展開時に元のパーミッション・所有者・タイムスタンプを維持する。root で実行すると GNU tar はデフォルトでパーミッションを保持するけど、バックアップ復元時には明示的に -p を付けて確実にしておくほうが安心。

まとめ

パターンはシンプルだ。tar がまとめて、圧縮ツールが縮める。ほぼ毎回両方使う。 普段の作業は tar --zstd -cftar xf で 9 割カバーできる。クロスプラットフォーム共有なら zip、ソフトウェア配布で 1KB でも削りたいなら xz

最低限覚えておくコマンド:

bash
# 作成(zstd、モダンな環境)
tar --zstd -cf archive.tar.zst directory/

# 作成(gzip、万能互換)
tar czf archive.tar.gz directory/

# 展開(どの形式でも自動検出)
tar xf archive.tar.gz

# 展開前に中身を確認
tar tf archive.tar.gz

# クロスプラットフォーム共有
zip -r archive.zip directory/

tar と組み合わせる CLI ツールの全体像は CLI ツールマップ で。ファイル検索は find ガイド、リモート転送は ssh・rsync ガイド を参照。