miau's blog?

ack(grep するやつ)

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

とするだけです。

■第一印象(以前使ったときの)

実行結果はこんな感じ。

ack0

これ見て、あんま意味ないじゃんと思ってました。Devas に比べると、

(1) 出現位置にジャンプできない
(2) Windows だと文字列の出現位置がハイライト表示されない
(3) KWICn(マッチした語句がセンタリングされる)じゃない
(4) 文字コードの自動判別がない?
(5) 置換が行えない

ということで。でも、ちゃんとマニュアルを見直してみると誤解してる部分もあったので、以下それぞれについて。

■「出現位置にジャンプできない」→誤解

ためしにサクラエディタから使ってみると評価が変わりました。Ctrl+F5「ファイル名を指定して実行」で

ack_sakura1

こんな感じで呼び出してやると・・・

ack_sakura2

ちゃんと ファイル名:行数 の形式になってる!ということは、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

とやって再度実行してみると・・・

ack1

あれー?うまくいかない。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)だとちゃんとハイライト表示できました。

ack2

ダメだったのは 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 のみの問題だったようで。お騒がせしました。
posted at 18:58:58 on 2009-03-06 by miau - Category: Perl No Trackbacks - Permalink

TrackBack

このエントリにトラックバックはありません
現在トラックバックは受け付けていません。

Comments

FILE wrote:

http://www.sixapart.jp/tech...
2009-03-07 15:28:55

miau wrote:

ご紹介ありがとうございます。putty 等のカラー表示に対応したターミナルエミュレータを使えば、リモートで実行した ack の結果をハイライト表示できる(+ページャとして lv -c を使えばカラー表示のままページングできる)というお話ですよね?

今回は Windows で完結する話だったのでこの方法は使わないのですが、役に立つ場面もありそうです。
2009-03-08 21:05:49

FILE wrote:

外していましたか。失礼致しました。
単に(WriteFileの差し替えに)管理者権限が必要…という問題でも無いのでしょうねぇ。
実際に試していないので、申し訳ありません。
2009-03-08 22:41:57

FILE wrote:

 最悪、"標準入力"から読み込んだエスケープシーケンスを解釈して、"標準出力"に出力するフィルタ を作れば良いのかと思い検索してみると、
先人を見つけました。
sephiebrain.jp/html/diary/200705.html#010105
 色を変えるだけであれば、以下のもの(VB.Net製)を改造するのも良さそうです。
scripting.cocolog-nifty.com/blog/2008/09/echo-e0ce.html
 Win32-Console-ANSIもANSI.xsで似たような処理(API呼び出し)をしているようなので、APIのhookが原因であれば、解決するかもしれません。
以上、実際に試してはいませんが、ご参考まで。
2009-03-15 21:22:52

miau wrote:

なるほどー・・・確かにそれで実現できそうですね。

おっしゃるとおり ANSI.xs でかなりの部分が実装されているので、Win32::Console::ANSI のインターフェイスをいじってフィルター作るのが楽そうです。意欲が沸いたら&時間が許せばチャレンジしてみます。ありがとうございます。
2009-03-17 08:40:13

FILE wrote:

 度々すみません。
 現状、特殊な環境(Windows 7 Beta)以外では問題無いと言う事で、余計に手間をかける必要は無いのでしょうけれど。
 他にも気になった事を書いておきます。検索してきた人の参考になればいいのですが。
・DEP(Data Execution Prevention)が原因かな とも思ったのですが、その場合はそこで処理が中断しそうですね。
・正攻法は、ANSI.xsのOutputDebugString(DEBUGSTR経由)の出力を見て、原因を探る事でしょうか。
 こちらも、Win32::Console::ANSIの再生成等、手間が掛かりそうですけど。
 関連:DebugView(OutputDebugStringの出力を読みとることができる)
 http://www.softantenna.com/...
2009-03-22 21:57:00

miau wrote:

ありがとうございます。DEP については、今回は(たぶんですけど)スタックやヒープにコードを載せたりはしてないので、これが原因ということはないのかなと思ってます。

正攻法は OutputDebugString を追うことなんですけど、おっしゃるとおりプリプロセッサで無効にされているのでコンパイルしなおさないとダメなんですよね・・・。コンパイル環境がないので、ひとまず保留ということにしてしまいました。

私も検索してきた人のために DbgView について補足しておきます。Vista(おそらく Win7 も)だとレジストリをいじったり DebugView のオプションを変更する必要ありです。詳細は以下のページのユーザコメント参照ということで。

OutputDebugString Function (Windows)
http://msdn.microsoft.com/e...
2009-03-23 04:50:47

Add Comments

現在コメントは受け付けていません。
お手数ですが、 こちら のコメント欄にでも記載していただければと思います。