ack -- better than grep, a power search tool for programmers
Perl 製の grep ツール。
ソースコード検索の ack がよさげな件: blog.bulknews.net
で見かけたときにちょっと試してその後すぐ使わなくなってたわけですが。今回また使ってみたのでそのお話。
■前置き
私は他人のコードのメンテナンスをメイン業務にしていた時期がありまして。構成や設計指針がわからないので、影響調査なりなんなりで grep は結構やるほうです。しかも扱う環境が
・PHP と Perl と Born shell を連携してる環境
・ASP と C++ が混在してる環境
・設定ファイルに拡張子がついてない環境(
以前 blog にも書いたやつ)
といろいろなので、拡張子で絞込みを行わずに全ファイルを対象にして grep することが多いです。
で、拡張子で絞り込まずに grep すると SVN の管理ファイルも引っかかったりするので、
この辺 で書いた Devas の改造版を使っているわけです。
■きっかけ
ところが今回新しくセットアップした PC で SVN での管理ファイルを grep したくなりまして。Devas 改造版はパッチ作ってないからちょっと導入が面倒で・・・対象ファイルは Perl スクリプトだし、ack を再度試してみようかなと。
■インストール
ActivePerl が入ってれば、
ppm install App::Ack
とするだけです。
■第一印象(以前使ったときの)
実行結果はこんな感じ。
これ見て、あんま意味ないじゃんと思ってました。Devas に比べると、
(1) 出現位置にジャンプできない
(2) Windows だと文字列の出現位置がハイライト表示されない
(3) KWICn(マッチした語句がセンタリングされる)じゃない
(4) 文字コードの自動判別がない?
(5) 置換が行えない
ということで。でも、ちゃんとマニュアルを見直してみると誤解してる部分もあったので、以下それぞれについて。
■「出現位置にジャンプできない」→誤解
ためしにサクラエディタから使ってみると評価が変わりました。Ctrl+F5「ファイル名を指定して実行」で
こんな感じで呼び出してやると・・・
ちゃんと ファイル名:行数 の形式になってる!ということは、F12 を押せば該当箇所にちゃんとジャンプできると。ちゃんと ack --man には vim やら emacs と組み合わせる方法が載ってたけど、気づかなかったなぁ。
あとは文字列の出現位置がハイライトできれば嬉しい。これはマクロとかで対応できるかな?
■Windows だと文字列の出現位置がハイライト表示されない→やり方はあるらしい?
エディタ上はいいとして、これはコマンドライン上でのハイライトの話。Linux とかだとハイライトされるみたいだけど・・・。
と思ったら、Windows でやる方法も ack --man に載ってて、
BdP : Win32::Console::ANSI
を使えば OK と。書いてるとおり、
ppm install http://www.bribes.org/perl/ppm/Win32-Console-ANSI.ppd
とやって再度実行してみると・・・
あれー?うまくいかない。ack 側では Win32::Console::ANSI が認識されてるようで、ちゃんとコントロールコードは吐かれてるみたいだけど・・・Windows 7 とかヒネくれた環境のせいなのか、それ以外の原因なのか。どなたか標準的な環境でレポートしていただけると助かります。
ちなみにこの状態でも、サクラエディタから呼び出したときはコントロールコードは出力されないので通常使用には支障ないはず。気になるばあいは ack の呼び出し時に --nocolor オプションつけるか、
ppm uninstall Win32-Console-ANSI
とやってアンインストールする感じで。
ところで Windows でのハイライト方法を調べてたら cmd.exe の選択箇所をハイライトする方法なんてのも見つけた。長くなるのでこれはまた次項で。
■その他の問題は?
KWICn できないのと置換が行えないのは、そういうツールということであきらめるとして・・・文字コードの自動判別がないのは結構痛いような。ちょっと調べたら出てこなかった+今回はソース中に日本語少なそうなのでひとまず放置してますが、いいやり方があったら教えてください。
■注意点
使用する上で注意する必要がありそうなところも何箇所かあって。
まず検索対象とする拡張子が少ないので、-a つけないと .txt とかすら検索できない。これはちょっと不便かも。
あと ack はデフォルトだとカレントディレクトリを対象に検索をかける仕様。サクラエディタはカレントディレクトリが現在開いているファイルのディレクトリになる(※新規作成ファイルであれば、その直前に開いていたカレントディレクトリが引き継がれる。たまに新規作成ファイルを開いたままだとフォルダ消せなかったりするのはそのため。)ので、ひとつ上のディレクトリで検索したい場合は
ack -a <検索語句> ..
とかやる感じになりそう?ちょっと面倒だけど、使い方がわかってきたらマクロでも書こうかな。
■ついでに
この blog では何度も書いてるのでくどいかもしれませんが、関数の定義位置を探すのには grep しないで ctags を使いましょう。関数の呼び出し場所を特定したり(これは言語によっては gtags でできますが)影響調査を行うのに grep を使うんであって、定義位置を探すのに grep するのは時間の無駄ですよ。どうも周囲で ctags 普及率がいまいち上がってこないので念のため。
(2009-03-08 追記)
別の環境(WinXP x64+ActivePerl 5.8.9.825)だとちゃんとハイライト表示できました。
ダメだったのは Windows 7 Beta+ActivePerl 5.10.0.1004 の環境。Win32::Console::ANSI は WriteFile API を hook してるって話だから、どちらかというと Vista/Win7 あたりが原因のような気がする。
(2009-03-09 追記)
Vista SP1 + ActivePerl 5.8.8.822 の環境でも OK でした。
CPAN のほうには Win32::Console::ANSI が Vista で動かない旨の報告もされているようですが、1.03 までで解決されていたりもするようですし、関係ない気もします。
Active bugs for Win32-Console-ANSI
バグ報告の中で「ウィルス対策ソフトが悪さしてない?」というアドバイスがあったので切ってみた&UAC 周りも確認したつもりですが、やっぱりうまくいってません・・・。
(2009-06-24 追記)
ハイライト表示、Windows 7 RC + ActivePerl 5.10.0.1004 の環境だと問題ありませんでした。Windows 7 Beta のみの問題だったようで。お騒がせしました。
ご紹介ありがとうございます。putty 等のカラー表示に対応したターミナルエミュレータを使えば、リモートで実行した ack の結果をハイライト表示できる(+ページャとして lv -c を使えばカラー表示のままページングできる)というお話ですよね?
今回は Windows で完結する話だったのでこの方法は使わないのですが、役に立つ場面もありそうです。