macOS で .DS_Store を除外して zip ファイルを作成する方法

macOS で .DS_Store ファイルを除外して zip ファイルを作成する方法についてです。

zip コマンドの -x オプション

zip コマンドには -x というオプションがあり、これを使うと除外対象を指定することができます。 これですべての階層の .DS_Store を指定すると OK です。

zip -r output.zip -r source/ -x '*/.DS_Store'

以下サンプルです。

# `-x` オプションを指定しなかった場合
$ zip -r tmp1.zip tmp
adding: tmp/ (stored 0%)
adding: tmp/.DS_Store (deflated 97%)
adding: tmp/hello.txt (stored 0%)
# `-x` オプションを指定した場合
$ zip -r tmp2.zip tmp -x '*/.DS_Store'
adding: tmp/ (stored 0%)
adding: tmp/hello.txt (stored 0%)

.DS_Store を明示的に除外するスクリプトを書いてももちろん OK です。 次のコードは Python で書いた場合のサンプルです。

import zipfile
from pathlib import Path
from typing import Iterable


def compress_dir(zip_out: Path, directory: Path, skipped_names: Iterable[str]):
    """Compresses a directory into a zip file."""
    if zip_out.exists():
        message = 'Specified zip file already exists: "{}".'.format(zip_out)
        raise Exception(message)

    with zipfile.ZipFile(str(zip_out.absolute()), 'w') as z:
        for f in directory.glob('**/*.*'):
            if f.name in skipped_names:
                continue

            z.write(f, f.relative_to(directory))


zip_out = 'output.zip'
directory = 'source'
skipped_names = ['.DS_Store']

compress_dir(zip_out, directory, skipped_names)

zip ファイルがある場合は -d オプション

すでに存在する zip ファイルに対してオプション -d を指定して zip コマンドを実行すると -x で指定されたファイルを取り除くことができます。 なので、ここに .DS_Store を指定すれば OK です。

$ zip -d tmp1.zip '*/.DS_Store'
deleting: tmp1/.DS_Store

以上です。

おまけ: 右クリックから実行できるようにする

この「 .DS_Store を除外した zip ファイルの作成」の処理を頻繁に行う場合は、 Finder の右クリックメニューから実行できるようにしておくと便利です。 以下設定手順です。

  1. Automator.app を立ち上げる
  2. Choose a type for your documentService を選択
  3. Service receives selectedfiles or folders in Finder.app を選択
  4. アイテム Run Shell Script を追加
  5. Shell には /bin/bash を選択
  6. Pass input には as arguments を選択
  7. 処理を実行するコマンドを記入
  8. 適当な名前で保存する

このようにしておくと Finder の右クリックメニューの Services からその処理を実行できるようになります。 メニュー名は 8 で付けた名前になります。

尚 7 の処理についてはファイル名を変数として受け取れるように記述する必要があります。 私の場合は .DS_Store を除外して zip ファイルを作る Python スクリプトを compress_excluding_ds_store.py といった名前で保存していて、その上で次のように書いています。

/path/to/python3 "path/to/compress_excluding_ds_store.py" "$@"

compress_excluding_ds_store.py は GitHub 上に置いているので興味のある方は参考にしてください。