Mac で p7zip を使って .DS_Store を除外したアーカイブを作成する

p7zip を使って .DS_Store の無いクリーンな ZIP を作成してみるテスト(・∀・)

まず、こんなディレクトリがあります。

bash
$ ls -a TEST
.DS_Store
test1.txt
test2.txt
test3.txt

これを普通に圧縮すると当然 .DS_Store も入ります。

bash
$ 7z a TEST.zip TEST

Creating archive TEST.zip

Compressing  TEST/.DS_Store     
Compressing  TEST/test1.txt     
Compressing  TEST/test2.txt     
Compressing  TEST/test3.txt

圧縮前に .DS_Store を削除するという方法もあるけど、.DS_Store も一応必要なファイルなので圧縮時に対象から外すようにしたいところ。p7zip のマニュアルを見ると以下のオプションで除外したいファイルを指定出来るらしい。

-x[r[-|0]]]{@listfile|!wildcard}
     Exclude filenames

意味不明w

http://sevenzip.sourceforge.jp/chm/cmdline/switches/exclude.htm に詳細なマニュアルがあった。

Syntax

-x[<recurse_type>]<file_ref>

<recurse_type> ::= r[- | 0]
<file_ref> ::= @{listfile} | !{wildcard}

See -i (Include) switch description for information about option parameters.
Examples

7z a -tzip archive.zip *.txt -x!temp.*

adds to the archive archive.zip all .txt files, except temp. files.

組み合わせとしては `-x` や `-xr`、`-xr-`、`-xr0` があるらしい。別のページに詳細が載ってるけど、サブディレクトリを辿るか辿らないかの指定。`-xr` と `-xr0` の違いはワイルドカード使用時に限定するかどうかっぽい。

Mac というか Bash だと ! は履歴の参照などに使うため、上のサンプル通りの方法では上手くいかないので以下のようにエスケープする。

bash
$ 7z a TEST.zip TEST -xr\!.DS_Store

Creating archive TEST.zip

Compressing  TEST/test1.txt     
Compressing  TEST/test2.txt     
Compressing  TEST/test3.txt

これらのファイル指定は @listfile にまとめておけるらしい。

これを Automator を使ってサービスに登録しておけば右クリックメニューで使えるようになる。Automator のシェルスクリプトは $HOME/.bashrc を読み込んでいないのでパスが通るように $HOME/.bashrc を先に読ませる(MacPorts でも Homebrew でも動くように)。複数のファイルを選択しても動作するように引数でファイルのパスを取得するようにして、アーカイブ名は引数の1番を利用すればカレントディレクトリにアーカイブが作成される。

ShellScript
. $HOME/.bashrc
7z a "$1".zip "$@" -xr\!.DS_Store

無圧縮 ZIP を作成する場合は -mx=0 を追加する。これは複数の音楽ファイルや画像ファイルをひとつにまとめてプレーヤーやビューアで開くときなんかに使える。

ShellScript
7z a -mx=0 "$1".zip "$@" -xr\!.DS_Store

作ったアーカイブの内容を確認は 7z l で出来る。

bash
$ 7z l archive.zip

.DS_Storeチェックだけをするなら grep などをパイプで繋げばよい。

bash
$ 7z l archive.zip | grep ".DS_Store"

サービスに登録するとこんな感じ。

Services

~/.bashrc に関数として登録しておく

最初に ~/.bashrc を読み込むなら関数として書いてしまった方がターミナルでもそのまま使えるので便利かも。

~/.bashrc
p7z_zip0(){
    7z a -mx=0 "${1}.zip" "$@" -xr\!.DS_Store
}
p7z_zip9(){
    7z a -mx=9 "${1}.zip" "$@" -xr\!.DS_Store
}

Automator の方は関数名を書いておく。

例)圧縮レベル0

Automator
# 入力の引渡し方法:引数
. ~/.bashrc
p7z_zip0 "$@"

例)圧縮レベル9

Automator
# 入力の引渡し方法:引数
. ~/.bashrc
p7z_zip9 "$@"

これならコマンドの修正をするときに Automator を開かずに ~/.bashrc を編集するだけでいいし、Automator でファイルを上書きしてショートカットの割り当てが外れるのも防げる。

ターミナルで使う場合も関数名と入力ファイル名だけを入力すればいい。

bash
# 入力
$ p7z_zip0 file1 file2 file3

# 実際に実行されるコマンド
$ 7z a -mx=0 "file1.zip" "file1" "file2" "file3" -xr\!.DS_Store

Automator のアクションには「リストから選択」というのがあるので、入力を stdin で受け取って「リストから選択」に出力すれば GUI でファイルを除外することも出来たりする。grep などと組み合わせて拡張子を指定するのも面白いかも。

Automator Runner

あとは試してないけど、第一引数を圧縮レベルに設定するようにして条件分岐すればひとつの関数で済ませられそう(その場合は第一引数の文字列判定と引数個数をチェックしたほうがいいかも)。Finder に表示するサービスもひとつにするなら圧縮レベルを設定するダイアログを表示するようにしないといけないですね。そこまでするなら keka 使った方が早いっていう…(Keka を使う場合は "Exclude Mac resource forks" にチェックを入れてあげれば .DS_Store を除外してくれるみたいです)。

今回は .DS_Store を除外したアーカイブを作りたいっていう話だったので…

あとはお好みでっ!ヽ(゚д゚)ノ

 

続き→ちょっとシェルスクリプトを考えてみた