UNIX での全文検索には古来から grep が使われてきました。例えば console で
% grep -n module *.tex
とやると、カレントディレクトリの拡張子が tex であるファイルで "module" という 単語を含むものを見つけて、ファイル名と行番号、行の内容を書き出してくれます。 "module" の部分には、正規表現が使えます。例えば、
% grep -n "[0-9][0-9]-[0-9][0-9]-[0-9][0-9]" *.his
とすると、拡張子 his
のファイルから 96-08-01
みたいな文字列が含まれている所を検索出来ます。この辺は皆さん、御存知の
ことと思うので省略。詳しくは
% man grep
Mule/Emacs には標準で grep を Mule の中から呼び出すコマンドがついてい
ます。例えば ~/tex
というディレクトリにある
拡張子 tex
のファイルで、connection という単語を
含むものを検索したい場合、M-x cd RTN ~/tex RTN M-x grep RTN とする
と、ミニバッファで検索コマンドを聞いてくるので、
% grep -n connection *.tex
と答えて RTN を押します。
(grep -n
の部分は始めから挿入されてる。) すると、
別の窓に結果が表示されます。ここで C-x ` を押
していくと、次々に見つかった場所にタグジャンプできます。あるいは、検索
結果の中から特定の場所に飛びたい場合は、その行にカーソルを移動して
C-c C-c とすると、その場所に飛べます。
検索結果をもっと絞りこむことも出来るらしいですが、それはまたいつか...。
少くともここの計算機の grep は日本語ファイルの検索にも使えます。私は普
段はファイルは EUC で統一しているのですが、その場合は、
.emacs
に
(define-program-coding-system "*grep*" nil (cons *euc-japan* *euc-japan*))
とか書いておけばよろしいです。あるいはもっと大胆に、
(set-default-process-coding-system *euc-japan* *euc-japan*)
とするのも手かもしれません。
そして igrep です。これは、grep のインターフェースを改造したもので、一 番の売りはサブディレクトリにも対応したことです。(実際は、find と xargs を内部から呼び出しています。そういうわけで Windows95/NT で使う場合には、 grep だけでなく、これらのコマンドもインストールしておく必要があります。 (GNU-Win32 であれば、release-17.1 以上が必要だそうです。)
なお、Emacs-20.x では初めから同等の機能を持つものがあるみたいです。
因みに、igrep を使えるようにするには、neumann 上なら
.emacs
に
(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 を load-path 上に置いて、必要なら bytecompileしておけばよい です。
Linux の日本語化パッケージ (P)JE などにある t^2 さんがマルチバイト文字
に対応して下さった GNU grep は、SJIS と EUC に対応しています。私みたい
に日本語の文章はほとんど EUC で書いている人や、Windows や DOS なんかの
上で使っている人で SJIS で統一してる人などにはこれで十分でしょう。
igrep から日本語の文章を検索する場合も、EUC なら
.emacs
に
(define-program-coding-system "*igrep*" nil (cons *euc-japan* *euc-japan*))
と書いておくだけで OK.
ただし、最近の igrep.el
のバージョン 2.83 と
いうやつだと、shell-quote-argument
を使っ
て -0-9a-zA-Z_./
以外の文字を全て
\
でクォートしちゃいます。当然、日本語は化け化けに
なっちゃうので、igrep.el 2.83
なら 479 行目
にある (shell-quote-argument expression)
は単に
expression
としてやらないとまずいです。そんなわけで、私は
いまだに 2.70 辺りを使っています。
ディレクトリによっては複数の文字コードのファイルが混在している場合もあ ります。こんな時は JIS とか UNICODE にも対応し、できれば漢字コードを自 動判別してくれるような grep が欲しくなります。
このことに関しては、最近になって、 成田さんが書かれた lv についている lgrep というものを知りました。時間がないこともあって、ま だちょっとしか使ってないのですが(ご免なさい)、とても素敵なもののように 思います。複数の漢字コードを使ってらっしゃる方は是非試してみて下さい。 lv 自体も素晴しいです。ただ、実行速度は
GNU grep+mb > jvim 附属の jgrep > lgrep
なので、この辺が気になる人や普段は EUC で十分な人などは日常的に使う方は通常の grep にしておくのがよいかも。
使い分けをする場合、例えば (setq igrep-program nil)
としておけば、毎回どの grep を使うか聞いてきます。
自動的に exec-path 上の grep という文字列を含むプログラムファイルをテーブルにして持っているので、補完が効きます。
こうしておいても特に不便はないでしょう。
mule からは常に lgrep を使いたい方は、lv をコンパイル、インストールした後、
.emacs
に
(setq igrep-program "lgrep")
を加えるだけです。そうすると gzip 等で圧縮されたファイルを指定すると
zlgrep が無いと怒られますが、これは例えば zlgrep
を
zgrep
にリンクしておいて、環境変数 GREP
を lgrep に指定するか、それが嫌なら zgrep
(これはシェルスクリプト) の先頭付近で egrep
とかと並べて
*lgrep) grep=${LGREP-lgrep} ;;
みたいな行を加えておけば良いはずです。
lgrep を知る前は、jvim2.0r についてきた、文字コード自動判別機能つきの jgrep に行数を表示するパッチを当てたものを使っ てました。(行数に関するバグがあるそうです。北内さんが いくつかの不具合 を修正したソースを書かれています。)
置き換え方は lgrep の時と同様です。lgrep もこの jgrep も -e オプショ
ンがないので、.emacs
に更に
(setq igrep-expression-option nil)
と書いておく必要があるかもしれません。そうすると正規表現が
- で始まる時とかは気をつけた方がいい気もしますが、これは
igrep.el
の方で勝手に \
でエスケープしてくれるようです。
同様にどの find を使うかは、igrep-find-program で指定できま
すが、これは変更したい人は少ないでしょう。その他の option については
igrep.el
内の User variables の箇所を見て下
さい。
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 という
のもあるみたいです。また、後で説明するjam-zcat.elを入れておけば、そのまま C-c ` や C-c C-c で文書の
該当箇所に飛ぶことも出来ます。
(Cf. jam-zcat) これは zgrep を呼び出して
いるのですが、Linux とか使ってる場合に
/usr/doc/faq
の下を見る時なんか重宝します。
再帰的にサブディレクトリを検索したい場合は M-x igrep-find を使います。親元のディレクトリを指定するには File(s) のところで指定しても良いですし、M-x cd でディ レクトリを移るのもありでしょう。
Dired mode では、dired-do-igrep(-find)
を
使って、マークしたファイルやカーソルの下のファイルやディレクトリに
grep をかけることができます。
C-x ` でファイルを開いていくと沢山ファイルを開い
てしまって 面倒だという人もいますが、そういう場合は
C-x C-b でバッファメニューを開いてまとめて消せば
問題ないでしょう。私は .emacs
で
(global-set-key "\C-x\C-b" 'buffer-menu)
として、C-x C-b でバッファメニューを開いたときに カーソルもそこへ飛ばすようにしています。