UNIX での全文検索には古来から grep
が使われてきました。例えば端末で
lucy~$
grep -n module *.tex
とやると、カレントディレクトリの拡張子が tex であるファイルで "module" という単語を含むものを見つけて、ファイル名と行番号、行の内容を書き出してくれます。 "module" の部分には、正規表現が使えます。例えば、
lucy~$
grep -n "[0-9][0-9]-[0-9][0-9]-[0-9][0-9]" *.his
とすると、拡張子 his
のファイルから 96-08-01 みたいな文字列が含まれている所を検索出来ます。
この辺は皆さん、御存知のことと思うので省略します。詳しくは man grep
などして御自分でお調べ下さい。
Emacs には標準で grep を Emacs の中から呼び出すコマンドがついています。
例えば ~/tex
というディレクトリにある拡張子 tex
のファイルで、connection という単語を含むものを検索したい場合、
M-x cd RTN ~/tex RTN M-x grep RTN とすると、ミニバッファで検索コマンドを聞いてくるので、
lucy~$
grep -n connection *.tex
と答えて RTN を押します。
(grep -n
の部分は始めから挿入されてる。)
すると、別の窓に結果が表示されます。
ここで C-x ` を押していくと、次々に見つかった場所にタグジャンプできます。
あるいは、検索結果の中から特定の場所に飛びたい場合は、その行にカーソルを移動して C-c C-c とすると、その場所に飛べます。
そして igrep です。これは、grep のインターフェースを改造したもので、一番の売りはサブディレクトリにも対応したことです。 (実際は、find と xargs を内部から呼び出しています。 そういうわけで Windows95/NT で使う場合には、grep だけでなく、これらのコマンドもインストールしておく必要があります。 (GNU-Win32 であれば、release-17.1 以上が必要だそうです。)
なお、Emacs-20.x では初めから同等の機能を持つものがあるみたいです。
因みに、igrep を使えるようにするには、
.emacs.el
に
(autoload (function igrep) "igrep" "*Run `grep` PROGRAM to match EXPRESSION in FILES..." t) (autoload (function igrep-find) "igrep" "*Run `grep` via `find`..." t) (autoload (function dired-do-igrep) "igrep" "*Run `grep` on the marked (or next prefix ARG) files." t) (autoload (function dired-do-igrep-find) "igrep" "*Run `grep` via `find` on the marked (or next prefix ARG) directories." t)
などと書いておきます。その他にも egrep や fgrep を使う設定を書いておいても良いです。
詳しくは igrep.el
の先頭の方に書いてあるので、省略します。
他のマシンでは、更に igrep.el (2.93) を load-path 上に置いて、必要なら bytecompileしておけばよいです。
Linux の日本語化パッケージ (P)JE などにある t^2 さんがマルチバイト文字に対応して下さった GNU grep は、SJIS と EUC に対応しています。 私みたいに日本語の文章はほとんど EUC で書いている人や、Windows や DOS なんかの上で使っている人で SJIS で統一してる人などにはこれで十分でしょう。
ただし、少なくとも igrep.el
のバージョン 2.83 以降では、shell-quote-argument
を使って -0-9a-zA-Z_./
以外の文字を全て \
でクォートしちゃいます。
Emacs 20 だと日本語が化け化けになってしまったりしたのですが、
Emacs 21 では取り敢えず大丈夫なようです。
(Emacs 20 では igrep.el 2.93
なら 510 行目にある (shell-quote-argument expression)
は単に expression
としてやらないとまずいです。)
ディレクトリによっては複数の文字コードのファイルが混在している場合もあります。 こんな時は JIS とか UNICODE にも対応し、できれば漢字コードを自動判別してくれるような grep が欲しくなります。 こういう grep としては、成田さんが書かれた lv についている lgrep というものが良い感じです。 (ちなみに、私は less の代わりに lv を使っています。) 複数の漢字コードを使ってらっしゃる方は是非試してみて下さい。 ただ、実行速度は
GNU grep+mb > jvim 附属の jgrep > lgrep
なので、この辺が気になる人や普段は EUC で十分な人などは日常的に使う方は通常の grep にしておくのがよいかも。
使い分けをする場合、例えば (setq igrep-program nil)
としておけば、毎回どの grep を使うか聞いてきます。
自動的に exec-path 上の grep という文字列を含むプログラムファイルをテーブルにして持っているので、補完が効きます。
こうしておいても特に不便はないでしょう。
Emacs からは常に lgrep を使いたい方は、lv をコンパイル、インストールした後、
.emacs.el
に
(setq igrep-program "lgrep") (setq igrep-expression-option nil)
を加えるだけです。
(下の行は、lgrep
には -e
というオプションがないため。)
そうすると gzip 等で圧縮されたファイルを指定すると
zlgrep
が無いと怒られますが、これは、
まず zlgrep
を zgrep
にリンクします。
そして、環境変数 GREP を lgrep
に指定するか、
それが嫌なら zgrep
(これはシェルスクリプト) の先頭付近で egrep
とかと並べて
*lgrep) grep=${LGREP-lgrep} ;;
みたいな行を加えます。
これで OK なはずです。
lgrep
を知る前は、jvim2.0r についてきた文字コード自動判別機能つきの jgrep
に行数を表示するパッチを当てたものを使ってました。
(行数に関するバグがあるそうです。北内さんが
いくつかの不具合を修正したソースを書かれています。)
置き換え方は lgrep
の時と同様です。
lgrep
と同様 jgrep
も -e
オプションがないので、.emacs.el
には次のように記すことになります。
(setq igrep-program "jgrep") (setq igrep-expression-option nil)
そうすると正規表現が - で始まる時とかは気をつけた方がいい気もしますが、
実はこれは igrep.el
の方で勝手に \
でエスケープしてくれるようです。
同様にどの find を使うかは、igrep-find-program で指定できま
すが、これは変更したい人は少ないでしょう。その他の option については
igrep.el
内の User variables の箇所を見て下
さい。
ところで、lgrep はデフォルトでは出力を iso-2022-jp で出します。
(インストールの仕方にもよると思いますが。)
この場合、出力バッファが文字化けしてしまうことがあるので、.lv
に -Oej
という行を加えておくと、EUC Japan で出力してくれます。
ちなみに私は -c
という行も加えています。
こうしないと私の環境では lv
でスクロールしたときに反転してしまうので。
これは今の所 unicode を使うものしか成功していません。 iso-2022-jp-2 あたりのファイルでも latin-1 な文字を検索できると嬉しいのですが...。
が、逆に例えば utf-8 で書かれたファイルを igrep 経由で検索する場合なら、上の日本語の設定で大丈夫です。
M-x igrep とするとミニバッファで検索語を聞い てくるので、例えば、
grep Expression: grep
のように入力すると、次にファイルを聞いてきますので、
grep File(s): *.txt
みたいに答えます。結果は *igrep*
という名前のバッ
ファに表示されます。ここで C-x ` とすると、検
索されたファイルを自動的に読み込み、該当行にジャンプします。更に
C-x ` を繰り返せば、次々と検索された行に飛んでいきます。
また *igrep*
バッファに移って目標とする行にカーソルを動かして C-c C-c とすると、その行に飛びます。
ディレクトリは何も指定しない場合は Emacs にとっての現在ディレクトリ、
即ち C-x C-f とした時にデフォルトで見る行が使われるようです。
ファイル検索の際に、*.gz のように拡張子 gz
を指定した場合は、
zgrep
を自動的に呼出してくれます。
M-x zgrep というのもあるみたいです。
そのまま C-c ` や C-c C-c で文書の該当箇所に飛ぶことも出来ます。
これは zgrep を呼び出しているのですが、Linux とか使ってる場合に
/usr/doc/faq
の下を見る時なんか重宝します。
再帰的にサブディレクトリを検索したい場合は M-x igrep-find を使います。 親元のディレクトリを指定するには File(s) のところで指定しても良いですし、 M-x cd でディレクトリを移るのもありでしょう。
Dired mode では、dired-do-igrep(-find)
を使って、マークしたファイルやカーソルの下のファイルやディレクトリに grep をかけることができます。
このコマンドを特定のキーに割り当てる方法については、
dired のキー割り当ての項
に書かれているようにフックを使います。
C-x ` でファイルを開いていくと沢山ファイルを開いてしまって 面倒だという人もいますが、
そういう場合は C-x C-b でバッファメニューを開いてまとめて消せば
問題ないでしょう。私は .emacs.el
で
(global-set-key "\C-x\C-b" 'buffer-menu)
として、C-x C-b でバッファメニューを開いたときに カーソルもそこへ飛ばすようにしています。