2015/05/22

Emacsのファイルマネージャ機能Diredと一括名前変更に便利なWDired

本記事はGNU Emacsの内蔵ファイルマネージャ機能 “Dired” についてをまとめたものとなる。

元の記事は2007年7月に書かれたが、この度Emacsのバージョン24系にて動作を検証し直し、記事内の設定例の内容も見直した上で全体の表現なども大幅に調整した。

  1. Diredの長所と短所
    1. 長所
    2. 短所
  2. カスタマイズの設定例
  3. Diredモードの開始
  4. 基本的な操作
    1. ディレクトリ階層の移動
    2. ディレクトリの作成と項目削除
    3. ファイルやディレクトリに対する操作
    4. Dired上でfindコマンドを実行
  5. ファイルやディレクトリのリストを編集する形の一括名前変更(WDired)

Diredの長所と短所

長所

  • (GUI環境ではなく)端末の中で作業していても、コマンドをいちいち入力することなく能率よくファイルの処理ができる
  • エディタの内蔵機能のため、テキストファイルを選択するとそのまま編集に入ることができる
  • 対応する形式の書庫ファイルの中の項目一覧を表示したり、中のファイルを開いて保存(書庫を更新)したりできる
  • パターン(特定の拡張子など)に合致したファイルやディレクトリのみを一覧してその中で操作を行うことができる
  • 機能の拡張やカスタマイズの自由度が高い
  • テキスト編集による一括名前変更機能(WDired)が非常に便利

短所

  • GNU Emacsの基本的な操作や設定/カスタマイズの形を少しは知っている必要がある
    • ファイルマネージャ機能の呼び出し操作自体もEmacs独特なので、Emacsが初めてという人には少し抵抗があるかもしれない
  • 既定の状態では使いにくいと感じる場合が多いかもしれない(ある程度のカスタマイズが必要な場合が多い)
    • 一覧内のファイルサイズがバイト単位だったりディレクトリの項目の末尾に “/” がなかったりなど
  • ファイルやディレクトリに対する多くの操作がキーを押すことによって行えるが、この割り当てに慣れるまでが使いにくいと感じるかもしれない
    • Emacsのメニューを隠す設定をしていなければメニューからの操作も可能で、キーの対応も参照可

カスタマイズの設定例

Diredを使用すること自体は特に設定を記述せずにできるが、使いにくい部分を感じる場合が多いため、カスタマイズを行うことを推奨する。

下は設定例。

[一部]ファイル名:[ホームディレクトリ]/.emacs.el
;; Diredと直接関係ないが、削除確認などでyes/noと入力後Enterを押す代わりに
;; y/nのどちらかのキーを押すだけでよくなる設定
(fset 'yes-or-no-p 'y-or-n-p)

;; GTK+のEmacsでファイル選択時のGUIダイアログを無効化
(setq use-file-dialog nil)

;; Windows上のlsのエミュレーション実装でディレクトリをファイルより上に表示する
;(setq ls-lisp-dirs-first t)
;; 同実装において出力される日時の形式を "YYYY-MM-DD hh:mm" にする指定
;(setq ls-lisp-format-time-list '("%Y-%m-%d %H:%M" "%Y-%m-%d %H:%M"))

;; 各種設定
(add-hook 'dired-load-hook
  '(lambda ()
    ;; ディレクトリを再帰的にコピー可能にする
    (setq dired-recursive-copies 'always)

    ;; ディレクトリを確認なしで再帰的に削除可能にする(使用する場合は注意)
    ;(setq dired-recursive-deletes 'always)
    ;; 対象の最上位ディレクトリごとに確認が出る形
    (setq dired-recursive-deletes 'top)

    ;; lsのオプションを指定 (詳しくはlsのmanページなどを参照)
    ;; Windows以外向け
    ;; "l" (小文字のエル)は必須
    ;; ディレクトリをファイルよりも上に表示するには
    ;;   "--group-directories-first" を含める
    ;; 出力される日時の形式を "YYYY-MM-DD hh:mm" にするには
    ;;   "--time-style=long-iso" を含める
    (setq dired-listing-switches "-Flha --time-style=long-iso --group-directories-first")   ; "." と ".." が必要な場合
    ;(setq dired-listing-switches "-GFlha --time-style=long-iso --group-directories-first") ; グループ表示が不要な場合
    ;(setq dired-listing-switches "-FlhA --time-style=long-iso --group-directories-first")  ; "." と ".." が不要な場合

    ;; find-dired/find-grep-diredで、条件に合ったファイルを一覧する際の出力形式
    ;; ([findのオプション(出力に関係するもの)] . [LSのオプション(出力解析上の指定)])
    (setq find-ls-option '("-print0 | xargs -0 ls -Flhatd --time-style=long-iso" . "-Flhatd --time-style=long-iso"))

    ;; 新規バッファを作らずに移動するコマンド "dired-find-alternate-file" は
    ;; 標準では無効化されているので、使用したい場合は下の記述で有効にする
    (put 'dired-find-alternate-file 'disabled nil)
  )
)

;; 幾つかの部分の表示スタイルをカスタマイズ
;; "M-x describe-face" で "dired-" と入力してTab補完できる項目に適用可で
;; "M-x customize-face" で選択して簡易設定することもできる
(custom-set-faces
  '(dired-directory ((t (:foreground "#5fafff" :weight bold))))
  '(dired-symlink ((t (:foreground "#5fd7ff" :weight bold))))
  '(dired-flagged ((t (:background "red" :foreground "#eee" :underline t :weight bold))))
  '(dired-marked ((t (:underline t :weight bold))))
)

;; 以下の "dired-mode-map" を含む記述で必要
(require 'dired)
;; ファイル名をまとめて編集可能なWDiredモードに入るキー(下の例では "r")
;; 既定では "C-x C-q"
(define-key dired-mode-map (kbd "r") 'wdired-change-to-wdired-mode)
;; "Enter" を押したとき、新規バッファを作らずにディレクトリを開く
;; 既定では "a" を押したときにのみこの動作になる
(define-key dired-mode-map (kbd "RET") 'dired-find-alternate-file)
;; "a" を押したときにのみ新規バッファを作って開くようにする
;; 既定では "Enter" を押したときに新規バッファで開く
(define-key dired-mode-map (kbd "a") 'dired-find-file)
;; "^" が押しにくい場合 "c "でも上の階層に移動できるようにする
;(define-key dired-mode-map (kbd "c") 'dired-up-directory)

WDiredについてはEmacsのバージョン22以上では標準で搭載されており、古いバージョンのEmacs向けに単独で公開されているバージョン(wdired.el)が個人用のディレクトリなどに残っていてこれを読み込む記述を設定ファイル内でしている場合はEmacsのバージョン24以上ではうまく動作しないので注意。

Diredモードの開始

Emacsの動作中、Ctrl-xを押した後にdを押す[1]と、画面下部の “ミニバッファ” と呼ばれる領域に

Dired (directory):

と表示され、その右の部分でディレクトリの入力をする状態になるので、開きたいディレクトリ階層を入力してEnterを押すか、もしくは通常のファイルを開く操作[2]でディレクトリを指定するとDiredモードに切り替わり、指定したディレクトリの一覧が表示される。入力の途中でCtrl-xCtrl-cを間違って押してしまった場合はCtrl-gを押して取り消してから入力を続行する。

前者の方法で “~/.*rc” のようにワイルドカード指定[3]を含めて入力すると、一致した項目のみの一覧が表示される。[4]

(ワイルドカード指定による出力例)
  /home/user:
  wildcard .*rc
  -rw-r--r-- 1 user users 1.9K 2007-06-29 20:30 .asoundrc
  -rw-r--r-- 1 user users 3.9K 2007-06-29 21:49 .bashrc
(以下略)

基本的な操作

  /home/user/.wine:
  合計 1.1M
  drwxr-xr-x 2 user users 4.0K 2007-06-24 15:26 dosdevices/
  drwxr-xr-x 5 user users 4.0K 2007-06-03 20:21 drive_c/
  -rw-r--r-- 1 user users 875K 2007-07-01 20:34 system.reg
  -rw-r--r-- 1 user users 192K 2007-07-01 20:34 user.reg
  -rw-r--r-- 1 user users 2.5K 2007-07-01 20:34 userdef.reg

このような、lsコマンドの出力のような領域(バッファ)の中をカーソルで移動[5]しながら、ファイル操作のキーを押していく。

ディレクトリの項目だけを探してたどりたい場合、<>のキーが選択に役立つ。

ディレクトリ内の項目を再読み込みするにはgを押す。

ディレクトリ階層の移動

ディレクトリ項目の行にカーソルがある状態でEnterを押すと

  /home/user/.wine/drive_c:
  合計 12K
  drwxr-xr-x 22 user users 4.0K 2007-07-01 16:09 Program Files/
  (以下略)

のように、表示されるディレクトリが移る。一つ上の階層へ移動するには^を押す(キーは設定で変更可)か、設定でdired-listing-switchesに “-a” が含まれている場合(Windows以外のみ)は項目 “..” を選択する。

離れた階層を開きたい場合、ディレクトリを順にたどってもよいが、初めにDiredモードに入ったときの操作を再度行って移動したほうが楽な場合もある。

ディレクトリの作成と項目削除

Diredモード上で+キーを押すと

Create directory:

とミニバッファに表示されてディレクトリ名の入力になるので、名前を付けてEnterを押すと一覧の中に新しくディレクトリが作成され、表示が更新される。

この新しいディレクトリの名前の行でdを押すと

D drwxr-xr-x 2 user users 4.0K ...

一番左に削除フラグ “D” が付き、行も強調表示される。削除フラグを付けただけではそのファイルやディレクトリは実際には消えない。削除フラグや後述のマークは複数の項目に同時に付けることができる。

これを解除するには個別にuを押すか、U(Shift-u)で一括解除ができる。もしくはバッファの先頭にある現在のディレクトリ名の行にカーソルを移動してuを押してもよい。

削除したい項目(ファイルやディレクトリ)に削除フラグを付けたら、xで削除を実行する。確認がミニバッファに出るので、OKならyを、取り消す場合はnを押す。[6]

ファイルやディレクトリに対する操作

ファイルやディレクトリに対する操作は下のような流れとなる。

  1. 操作の対象を選択
  2. 行う操作に対応したキーを押す
  3. 操作の種類によって、パラメータ入力をしたり、実行確認をしたりする

複数の項目に対して操作を行う場合、mキーで選択マークを付けていく。マークを付けると一番左に “*” が付いて行も強調表示される。このマークの解除方法は先述の削除フラグと同様。

* -rw-r--r-- 1 user users 28K ...

項目の名前やファイルの内容による高度な選択方法もあるが、ここでは扱わない。

行う操作に対応したキーは基本的に大文字指定で、例えば、コピーはShiftを押しながらcを押し、コピー後のファイル名を入力してEnterを押す。

操作のキーについては、Emacsのメニューを隠す設定をしていなければ “Operate” メニューの中に表示される上にメニュー項目からの実行も可能なので、無理に覚えようとする必要はないが、よく使うものだけ下に紹介する。なお、削除マークを使わずに通常のマークを使って削除をすることもできる(操作のキーはD)。

操作キー
マークされた項目[7]を引数として 任意のコマンドを入力して実行(同期版)!
上の非同期版[8]&
コピーC
移動・名前変更[9]R
パーミッション(アクセス権・モード)変更M
選択した項目に対するシンボリックリンクを作成S

Dired上でfindコマンドを実行

findコマンドで条件に合ったファイルやディレクトリの一覧をDired上で表示し、その一覧内のファイルやディレクトリに対して操作を行うことができる。これを使うにはfindコマンドの使い方を理解している必要がある。

下は操作手順。

  1. Meta-xの後に “find-dired” と入力
  2. 検索したいディレクトリ(中のディレクトリも全てたどって調べる)を指定
  3. findコマンドの条件を指定(例: “-name \*.log -mtime +30”)
  4. 結果がディレクトリと同様に一覧表示され、開くなどの操作もディレクトリ内と同様に行える

ファイルやディレクトリのリストを編集する形の一括名前変更(WDired)

Diredモードの一覧表示時に “Ctrl-x Ctrl-q” (見出し:カスタマイズの設定例に書いてある設定ではr)を押す[10]とWDiredモードに入って画面左下の表示が “U:---” のような形になり、一覧がテキストファイルのように編集できるようになったことを示す[11]。手動で数個のファイル名をいじるだけのような場面でも楽に作業ができるので重宝する。

下の例では、番号部分が一桁の.jpgファイルの先頭に “0” を付ける操作を行う。元はこの状態。

-rw-r--r-- 1 user users 35K 2007-04-29 16:52 img1.jpg
-rw-r--r-- 1 user users 43K 2007-04-29 16:52 img10.jpg
-rw-r--r-- 1 user users 35K 2007-04-29 16:52 img11.jpg
-rw-r--r-- 1 user users 35K 2007-04-29 16:52 img2.jpg
-rw-r--r-- 1 user users 35K 2007-04-29 16:52 img3.jpg
-rw-r--r-- 1 user users 35K 2007-04-29 16:52 img4.jpg
-rw-r--r-- 1 user users 35K 2007-04-29 16:52 img5.jpg
-rw-r--r-- 1 user users 35K 2007-04-29 16:52 img6.jpg
-rw-r--r-- 1 user users 35K 2007-04-29 16:52 img7.jpg
-rw-r--r-- 1 user users 35K 2007-04-29 16:52 img8.jpg
-rw-r--r-- 1 user users 35K 2007-04-29 16:52 img9.jpg
...

ここで “Meta-x replace-regexp” を実行し、 “img\([0-9].jpg\)” を “img0\1” で置換するように指定すると

-rw-r--r-- 1 user users 35K 2007-04-29 16:52 img01.jpg
-rw-r--r-- 1 user users 35K 2007-04-29 16:52 img02.jpg
-rw-r--r-- 1 user users 35K 2007-04-29 16:52 img03.jpg
-rw-r--r-- 1 user users 35K 2007-04-29 16:52 img04.jpg
-rw-r--r-- 1 user users 35K 2007-04-29 16:52 img05.jpg
-rw-r--r-- 1 user users 35K 2007-04-29 16:52 img06.jpg
-rw-r--r-- 1 user users 35K 2007-04-29 16:52 img07.jpg
-rw-r--r-- 1 user users 35K 2007-04-29 16:52 img08.jpg
-rw-r--r-- 1 user users 35K 2007-04-29 16:52 img09.jpg
-rw-r--r-- 1 user users 43K 2007-04-29 16:52 img10.jpg
-rw-r--r-- 1 user users 35K 2007-04-29 16:52 img11.jpg
...

という感じに置換ができる。

名前の一部を単純に置換したいなら、 “Meta-x replace-string” で、置換前文字列と置換後文字列を指定する。

この変更を適用してWDiredモードを抜けるには、 “Ctrl-c Ctrl-c” を押せばよい。[12]間違えたときなど、変更を破棄してWDiredモードを抜けたい場合には、 “Ctrl-c Esc” を押す。[13]

なお、GUI環境で作業できる場合、ファイル名の置換を含めた一括変更にはGUIファイルマネージャThunarの一括名前変更機能を使う方法もあり、変更後の名前をプレビューしながら条件を書けたりもする。

使用したバージョン:
  • GNU Emacs 24.4.1
[1]: メニューでは “File - Open Directory”
[2]: 既定ではCtrl-xを押した後にCtrl-fを押し、ミニバッファに “Find file:” と表示されて開く対象を入力する・メニューでは “File - Open File” を選択する
[3]: 項目名、つまり最後の “/” の後ろにのみ使用可
[4]: 後者の方法でこれを指定すると該当するファイル全てが開かれるので注意
[5]: 矢印キーなどでそのまま移動してもよいし、Ctrl-sで検索をかけて飛んでもよい
[6]: 見出し:カスタマイズの設定例にて yn を押して決定する設定をしているためで、既定では “yes” か “no” と入力後Enterを押す面倒な操作になる
[7]: なければカーソル位置の項目
[8]: 出力は専用のバッファに表示され、終了時にはミニバッファに通知が表示される・処理に時間がかかるものなどに適する
[9]: 移動の場合は移動先のディレクトリ、名前変更の場合は変更後の名前を指定・名前変更と移動を同時にする場合、 “[移動先ディレクトリ]/[変更後のファイル名]” を指定
[10]: メニューでは “Immediate - Edit File Names”
[11]: 一部を編集すると、変更を適用するか取り消すまで、通常のファイルと同様に “U:**-” となる
[12]: メニューでは “WDired - Commit Changes”
[13]: メニューでは “WDired - Abort Changes”