igrep について

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]" *.his    

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

    % man grep    
などして御自分でお調べ下さい。:-P

Mule の中から 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 について

そして 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.elload-path 上に置いて、必要なら bytecompileしておけばよい です。

日本語の検索 (その1)

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 辺りを使っています。

日本語の検索 (その2)

ディレクトリによっては複数の文字コードのファイルが混在している場合もあ ります。こんな時は 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 が無いと怒られますが、これは例えば zlgrepzgrep にリンクしておいて、環境変数 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 との連継

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 でバッファメニューを開いたときに カーソルもそこへ飛ばすようにしています。


[Mule のページに戻る]