dittoに-c -kを指定すると、ディレクトリやファイルからzipファイルを作成できる。--keepParentと--sequesterRsrcを組み合わせると、Finderの「圧縮」と同じ形式のzipファイルになる。

参考: 【ditto】コマンドでディレクトリをコピーする

-c -kでzipファイルを作成する

-cはアーカイブの作成、-kはPKZip(zip)形式の指定である。-kを省略するとCPIO形式になる。

検証用のproject/a.txtには、拡張属性com.example.noteを付けてある。

$ ditto -c -k project project.zip
$ unzip -l project.zip
Archive:  project.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  09-27-2026 09:26   sub/
        6  09-27-2026 09:26   sub/b.txt
      163  09-27-2026 09:26   sub/._b.txt
      163  09-27-2026 09:26   ._sub
        6  09-27-2026 09:26   a.txt
      196  09-27-2026 09:26   ._a.txt
---------                     -------
      534                     6 files

zipファイルにはprojectディレクトリの中身だけが入り、project/ディレクトリ自体は含まれない。

._a.txtのような._で始まるファイルは、AppleDouble形式のファイルである。dittoは拡張属性などのメタデータをデフォルトで保持するため、メタデータを持つファイルごとに._ファイルを作ってzipに格納する。macOSでは、ユーザーが明示的に付けていなくてもcom.apple.provenanceなどの拡張属性がファイルに付くため、多くのファイルに._ファイルができる。

CPIO形式のアーカイブについては【ditto】コマンドでCPIOアーカイブを作成・展開する を参照。

--keepParentで親ディレクトリごと格納する

--keepParentを指定すると、コピー元のディレクトリ名をzipファイルの中に含める。

$ ditto -c -k --keepParent project project.zip
$ unzip -l project.zip
Archive:  project.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  09-27-2026 09:26   project/
        0  09-27-2026 09:26   project/sub/
        6  09-27-2026 09:26   project/sub/b.txt
      163  09-27-2026 09:26   project/sub/._b.txt
      163  09-27-2026 09:26   project/._sub
        6  09-27-2026 09:26   project/a.txt
      196  09-27-2026 09:26   project/._a.txt
---------                     -------
      534                     7 files

展開したときにproject/ディレクトリが作られるため、展開先にファイルが散らばらない。配布用のzipファイルを作る場合は--keepParentを付けておくとよい。

ファイル単体を指定した場合も、--keepParentを付けると親ディレクトリ名が含まれる。

$ ditto -c -k --keepParent project/a.txt one.zip
$ unzip -l one.zip
Archive:  one.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        6  09-27-2026 09:26   project/a.txt
      196  09-27-2026 09:26   project/._a.txt
---------                     -------
      202                     2 files

--sequesterRsrcでメタデータを__MACOSXにまとめる

--sequesterRsrcを指定すると、._ファイルを__MACOSX/ディレクトリの下にまとめて格納する。

$ ditto -c -k --sequesterRsrc --keepParent project project.zip
$ unzip -l project.zip
Archive:  project.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  09-27-2026 09:26   project/
        0  09-27-2026 09:26   project/sub/
        6  09-27-2026 09:26   project/sub/b.txt
        0  09-27-2026 09:26   __MACOSX/
        0  09-27-2026 09:26   __MACOSX/project/
        0  09-27-2026 09:26   __MACOSX/project/sub/
      163  09-27-2026 09:26   __MACOSX/project/sub/._b.txt
      163  09-27-2026 09:26   __MACOSX/project/._sub
        6  09-27-2026 09:26   project/a.txt
      196  09-27-2026 09:26   __MACOSX/project/._a.txt
---------                     -------
      534                     10 files

man dittoでは、ditto -c -k --sequesterRsrc --keepParentをFinderの「圧縮」と同様のzipファイルを作るコマンド例として紹介している。ditto -x -kで展開すると、__MACOSX/内のメタデータは元のファイルに復元される。unzipコマンドで展開すると、__MACOSX/ディレクトリがそのまま残る。

$ ditto -x -k project.zip out1
$ find out1
out1
out1/project
out1/project/sub
out1/project/a.txt
out1/project/sub/b.txt
$ xattr -l out1/project/a.txt
com.apple.provenance:
com.example.note: hello
$ unzip -q project.zip -d out2
$ find out2
out2
out2/project
out2/__MACOSX
out2/project/sub
out2/project/a.txt
out2/__MACOSX/project
out2/project/sub/b.txt
out2/__MACOSX/project/._sub
out2/__MACOSX/project/sub
out2/__MACOSX/project/._a.txt
out2/__MACOSX/project/sub/._b.txt

zipファイルの展開については【ditto】コマンドでzipファイルを展開する を参照。

--norsrcでメタデータを含めない

macOS以外の環境へ渡すzipファイルで._ファイルや__MACOSX/が不要な場合は、--norsrcを指定する。

$ ditto -c -k --norsrc --keepParent project project.zip
$ unzip -l project.zip
Archive:  project.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  09-27-2026 09:26   project/
        0  09-27-2026 09:26   project/sub/
        6  09-27-2026 09:26   project/sub/b.txt
        6  09-27-2026 09:26   project/a.txt
---------                     -------
       12                     4 files

メタデータの扱いについては【ditto】拡張属性やACLを保持してコピーする を参照。

--zlibCompressionLevelで圧縮レベルを指定する

--zlibCompressionLevelで、zipファイルの圧縮レベルを0から9の範囲で指定できる。0は無圧縮、9は最も時間をかけて圧縮する。省略時はzlibのデフォルトの圧縮レベルを使う。

約2MBのテキストファイルで比較した結果は以下の通り。

$ seq 1 300000 > big/nums.txt
$ for l in 0 1 6 9; do ditto -c -k --norsrc --zlibCompressionLevel $l big big$l.zip; done
$ ditto -c -k --norsrc big bigdef.zip
$ stat -f "%z %N" big/nums.txt big0.zip big1.zip big6.zip big9.zip bigdef.zip
1988895 big/nums.txt
1989208 big0.zip
651294 big1.zip
636167 big6.zip
636281 big9.zip
636167 bigdef.zip

レベル0では元のファイルよりわずかに大きくなる。省略時はレベル6と同じサイズになった。レベル9はレベル6とほぼ同じサイズで、データによってはわずかに大きくなる場合もある。

参考

DITTO Command: Copy directory hierarchies, create and extract archives in macOS