[ホーム]-> [emacs]-> [活用法]-> [grep]

grep について

注意: Emacs 附属の grep でも find との連継ができるようになりましたが、dired との連継なども考えている人は、 igrep の項を御覧下さい。

1. grep の復習

UNIX での全文検索には古来から grep が使われてきました。例えば console で

    grep -n module *.tex

とやると、カレントディレクトリの拡張子が tex であるファイルで "module" という 単語を含むものを見つけて、ファイル名と行番号、行の内容を書き出してくれます。 "module" の部分には、正規表現が使えます。例えば、

    grep -n "[0-9][0-9]-[0-9][0-9]-[0-9][0-9]" *.txt

とすると、拡張子 txt のファイルから 96-08-01 みたいな文字列が含まれている所を検索出来ます。この辺は皆さん、御存知の ことと思うので省略。詳しくは man grep などとして御自分でお調べ下さい。

2. Emacs から grep

Emacs には標準で grep を Emacs の中から呼び出すコマンドがついています。 カレントディレクトリにある拡張子 tex のファイルで、etale という単語を含むものを検索したい場合、 M-x  grep  RTN とすると、ミニバッファで検索コマンドを聞いてくるので、

    grep -n -e etale *.tex

などと答えて RTN を押します。 (grep -n -e の部分は始めから挿入されてる。) すると、別の窓に結果が表示されます。 ここで C-x ` を押していくと、次々に見つかった場所にタグジャンプできます。 あるいは、検索結果の中から特定の場所に飛びたい場合は、その行にカーソルを移動してRTN ないしは C-c C-c とすると、その場所に飛べます。

別のディレクトリの下を探す場合は、コマンドラインで直接 ~/tex を指定するかすればよいですし、或いは ~/tex の下であれば、最初に M-x  cd  RTN  ~/tex  RTN  としてから同じことをしても良いです。 もっともこの場合は Emacs にとってのカレントディレクトリも変更されてしまいますが。

3. grep-find

grep-find は、grep のインターフェースを改造したもので、 find と xargs を呼び出すことで、サブディレクトリの検索をも行えるようにしたものです。 (そういうわけで Windows95/NT で使う場合には、grep だけでなく、これらのコマンドもインストールしておく必要があります。 GNU-Win32 であれば、release-17.1 以上が必要なようです。)

実際の使い方ですが、M-x grep-find とすると、ミニバッファに
    find . -type f -print0 | xargs -0 -e grep -n -e 

のようにして検索コマンドを聞いてきます。これを適当に編集すればよいです。 普通は単に最後に検索する正規表現を入れるだけです。 再帰的に検索を開始するディレクトリをカレントディレクトリから変更したい場合は、 find の次の . を別のディレクトリに変更します。後は grep の場合と同様です。

4. 日本語の検索とカスタマイズ

Linux の日本語化パッケージ (P)JE などにある t^2 さんがマルチバイト文字 に対応して下さった GNU grep は、SJIS と EUC に対応しています。私みたい に日本語の文章はほとんど EUC で書いている人はこれで十分でしょう。 この場合、何もしなくても EUC での日本語検索もうまくいくはずです。

ディレクトリによっては複数の文字コードのファイルが混在している場合もあ ります。こんな時は JIS とか UNICODE にも対応し、できれば漢字コードを自 動判別してくれるような grep が欲しくなります。

このことに関しては、最近になって、 成田さんが書かれた lv についている lgrep というものを知りました。時間がないこともあって、まだちょっとしか使ってないのですが(ご免なさい)、とても素敵なもののように思います。 複数の漢字コードを使ってらっしゃる方は是非試してみて下さい。 lv 自体も素晴しいです。ただ、実行速度は

   GNU grep+mb > jvim 附属の jgrep > lgrep

なので、この辺が気になる人や普段は EUC で十分な人などは日常的に使う方は通常の grep にしておくのがよいかもしれません。

ともかく、実際に良く使うコマンドをデフォルトで登録するには、 (setq grep-command "lgrep -n -Oej ") などのようにすればよいです。 オプションではなく、コマンド名だけを変更したいなら、 (setq grep-program "lgrep") です。

lgrep を知る前は、jvim2.0r についてきた、文字コード自動判別機能つきの jgrep に行数を表示するパッチを当てたものを使ってました。 (行数に関するバグがあるそうです。北内さんが いくつかの不具合を修正したソースを書かれています。)

置き換え方は lgrep の時と同様です。lgrep もこの jgrep も -e オプションがないので注意です。

同様にどの find を使うかは、grep-find-command などで指定できますが、 これは変更したい人は少ないでしょう。

5. dired との連継

6. 補足

C-x ` でファイルを開いていくと沢山ファイルを開いてしまって面倒だという人もいますが、 そういう場合は C-x C-b でバッファメニューを開いてまとめて消せば問題ないでしょう。 私は .emacs.el

(global-set-key "\C-x\C-b" 'buffer-menu)

として、C-x C-b でバッファメニューを開いたときにカーソルもそこへ飛ばすようにしています。


[ホーム]-> [emacs]-> [活用法]-> [grep]