dired で tar.gz 圧縮 その3

完成版, かな.
関数の作成は, plus さんに多くコメントのコメントを頂きました.
最終的なものも, plus さんが手を入れたものとなっています.
ありがとうございます. すごく勉強になりました.



tar.gz 圧縮をする.

(defun dired-do-tar-cvzf (output-filename arg)
 "マークしたファイルを tar cvzf でまとめて圧縮する."
 (interactive "FOUTPUT FILENAME: \nP")
 (or (when (string= "" (file-name-nondirectory output-filename))
       ;; 出力ファイル名が入力されていなかったらエラーとする.
       (message "ERROR: Output filename is empty."))
     (when (file-exists-p
            (setq output-filename
                  (concat output-filename (unless (string-match "\\.t\\(ar\\.\\)?gz$" output-filename) ".tar.gz"))))
       ;; 出力ファイル名と同じ名前のファイルが, 既にあった場合, 上書きするか問い合わせる.
       (not (y-or-n-p (concat "file " output-filename " exists. overwrite the file ?"))))
     ;; 実際に圧縮をする.
     (let (add-file)
       (when arg
         (while (y-or-n-p "ADD FILE?")
           (add-to-list 'add-file (file-relative-name (read-file-name "" nil nil t)))))
       (dired-do-shell-command (concat "tar cvzf " output-filename " *") nil
                               (append (dired-get-marked-files t) add-file)))))

使い方は, 以下のとおり.

  • dired でマークしたものをまとめて tar cvzf 形式で圧縮する.
  • コマンドを起動すると, 圧縮してできるファイル(出力ファイル)の名前の入力を促される.
    • このファイル名が空だとエラー.
    • 出力先ディレクトリに同じ名前のファイルがあると, 上書きするかどうか警告を出す.
    • 拡張子として, tar.gz か, tgz を入力しなかった場合, .tar.gz を自動で付加する.
  • 前置引数(C-u)を与えると, カレントディレクトリ以外にあるファイルも圧縮するメンバーとして追加できる.


ついでに, tar.bz2 版

(defun dired-do-tar-cjvf (output-filename arg)
 "マークしたファイルを tar cjvf でまとめて圧縮する."
 (interactive "FOUTPUT FILENAME: \nP")
 (or (when (string= "" (file-name-nondirectory output-filename))
       ;; 出力ファイル名が入力されていなかったらエラーとする.
       (message "ERROR: Output filename is empty."))
     (when (file-exists-p
            (setq output-filename
                  (concat output-filename (unless (string-match "\\.t\\(ar\\.bz2\\|bz\\)$" output-filename) ".tar.bz2"))))
;                  (replace-regexp-in-string "\\(\\.tar\\.bz2\\)?$" ".tar.bz2" output-filename)))
       ;; 出力ファイル名と同じ名前のファイルが, 既にあった場合, 上書きするか問い合わせる.
       (not (y-or-n-p (concat "file " output-filename " exists. overwrite the file ?"))))
     ;; 実際に圧縮をする.
     (let (add-file)
       (when arg
         (while (y-or-n-p "ADD FILE?")
           (add-to-list 'add-file (file-relative-name (read-file-name "" nil nil t)))))
       (dired-do-shell-command (concat "tar cjvf " output-filename " *") nil
                               (append (dired-get-marked-files t) add-file)))))

使い方は, tar.gz 版と同じ.
tar cjvf で作られる圧縮ファイルの拡張子は, tar.bz2 しか知らないから,
replace-regexp-in-string でチェックするのに戻した.

追記

plus さんの御指摘により, tar.bz2 以外に, tbz が使用されることがあるようです.
plus さんが示してくれた正規表現で, 両方チェックする形式に変更しておきました.
9行目が追加した行で, 10行目のコメント行が以前のものです.
情報, ありがとうございます.



キーを割当てるなら, こんな感じで.

(define-key dired-mode-map "\C-c\C-t" 'dired-do-tar-cvzf)
(define-key dired-mode-map "\C-c\C-b" 'dired-do-tar-cjvf)

空いてるキーに適当に割り当てといた.