Hatena::ブログ(Diary)

mooz deceives you

(about 'mooz) ; => "See http://mooz.github.com/index-ja.html"

 | 

September 11 (Sun), 2011

atool を使い dired のサポートする圧縮形式を増やす

atool を使い dired のサポートする圧縮形式を増やす設定を紹介する.

atool

atool <http://www.nongnu.org/atool/> というツールがある.

これは様々な圧縮形式・ツールに対するフロントエンドツールで,ファイルの拡張子から適切な圧縮形式を推測し,内部で適切なコマンドを呼び出してくれるという優れもの.

標準で搭載しているシステムは少ないが,たいていはソフトウェアリポジトリに入っている.例えば Ubuntu なら apt でインストールすることができる.

sudo apt-get install atool

使い方は簡単で,例えばファイル FILE を解凍する場合は次のようにすれば良い.

aunpack FILE

tar xvfgunzip など圧縮形式毎にコマンドを記憶する時代は終わった.こうして人間は退化していく.

dired の圧縮・解凍機能

dired というツールがある.

これは Emacs 上で動くファイラで,とりたてて「ここが優れている」という部分もないが,標準で付属してくるため未だ利用する者も多い.

さて,そんな dired にはファイルを圧縮・解凍するコマンドが存在する.デフォルトの状態ではファイルを選択した(ポイントを上に持ってきた)状態で Z キーを押すと,選択されたファイルが圧縮されている場合は解凍され,未圧縮の場合は gzip 形式で圧縮される*1

圧縮ファイルの場合は解凍され,未圧縮ファイルの場合は圧縮されると書いた.では「そのファイルが圧縮されているかどうか」という判断はどのようにして行なっているのだろうか.dired は拡張子による判断方式を採用しており,内部に「このパターンにマッチする場合は圧縮ファイルなので,このプログラムを使って解凍すること」というルールを保持している.

そのルールの中身を覗いてみよう.

(defvar dired-compress-file-suffixes
  '(("\\.gz\\'" "" "gunzip")
    ("\\.tgz\\'" ".tar" "gunzip")
    ("\\.Z\\'" "" "uncompress")
    ;; For .z, try gunzip.  It might be an old gzip file,
    ;; or it might be from compact? pack? (which?) but gunzip handles both.
    ("\\.z\\'" "" "gunzip")
    ("\\.dz\\'" "" "dictunzip")
    ("\\.tbz\\'" ".tar" "bunzip2")
    ("\\.bz2\\'" "" "bunzip2")
    ;; This item controls naming for compression.
    ("\\.tar\\'" ".tgz" nil))
; snip

見ると,非常に限られたルールしか用意されていないことが分かる.広く使われている zip に対するルールすら見当たらない.

しかしながら,そこは拡張性の高い Emacs.この dired-compress-file-suffixes へは後から自由にルールを追加することができる.必要なものがあれば,自分で追加すれば良い.

といっても ("\\.zip\\'" "" "unzip") という具合に適切なプログラムを拡張子毎に追加していくのはさすがに骨が折れる.今回は,ここで先ほどの atool を利用することにした.とりあえず様々な圧縮形式を登録しておき,適切なプログラムは全て atool に判断してもらおうというわけだ.

dired の圧縮・解凍機能で atool を使う

というわけで dired の圧縮・解凍機能で atool を使うような設定を行なった.コードを以下に示す.

(defvar my-dired-additional-compression-suffixes
  '(".7z" ".Z" ".a" ".ace" ".alz" ".arc" ".arj" ".bz" ".bz2" ".cab" ".cpio"
    ".deb" ".gz" ".jar" ".lha" ".lrz" ".lz" ".lzh" ".lzma" ".lzo" ".rar"
    ".rpm" ".rz" ".t7z" ".tZ" ".tar" ".tbz" ".tbz2" ".tgz" ".tlz" ".txz"
    ".tzo" ".war" ".xz" ".zip"))

(eval-after-load "dired-aux"
  '(progn
     (require 'cl)
     (loop for suffix in my-dired-additional-compression-suffixes
           do (add-to-list 'dired-compress-file-suffixes
                           `(,(concat "\\" suffix "\\'") "" "aunpack")))))

この設定により,大抵の圧縮ファイルは dired で Z キーを押せば解凍できるようになる.

atool がサポートする圧縮形式のリスト *2 は man ページに記載されているため,以下のようなスクリプトを使って抽出した.

#!/usr/bin/env ruby
# Usage: man atool |& ./extract.rb

manpage = $stdin.read
manpage.sub!(/.*^ARCHIVE TYPES/, "")
manpage.sub!(/^CONFIGURATION.*/, "")

exts = manpage.
  scan(/\((\.(?:\.|[a-z0-9A-Z])+)(?:[ ,]+(\.(?:\.|[a-z0-9A-Z])+)\))*/).
  flatten.
  reject { |elem| elem.nil? }.
  map { |ext| ext.split(".")[-1] }.
  uniq

puts exts.join("\n")

まとめ

atool を使い dired のサポートする圧縮形式を増やす設定を紹介した.この圧縮・解凍機能は最低限の実装という印象で,実際に使ってみると様々な改善点*3が見えてくる.それらに関しては,気が向いたときにでも改善を図っていきたい.

*1dired-do-compress という関数が呼ばれている

*2my-dired-additional-compression-suffixes

*3:そのファイルが圧縮されるのか解凍されるのかが分からない.圧縮・解凍が同期的に行われブロックする.など.

sr10sr10 2011/10/03 04:05 unpってのもありますん。
でもatoolの方が高機能臭い。

moozmooz 2011/10/04 11:40 >sr10さん

おお,unp なんてものもあるのですね.そちらは unpack 専用と.

 |