イマドキの高速検索系ツールといったらagっしょ,みたいな気持ちでいたら最近はptというのがあるらしいですね.流行についていけないのでもうおじさんです. 他にもこの手のツールとしてripgrepなどがあります.流行り廃りの激しいツールのジャンルってありますよね.タスクランナーとか.
tl;dr
- 混在したエンコーディングを横断して検索したい?⇒ripgrepを使おう
- 圧縮したファイルの中も検索したい?⇒agを使おう
- バックレファレンスと先/後読みを使いたい?⇒agを使おう
- 独自のファイル形式を定義したい?⇒ripgrepを使おう
- 速いほうがいい?⇒ripgrepを使おう
- ポータブルなシングルバイナリが欲しい?⇒ptを使おう
agの復習
そもそもagが生まれた?背景はどういったものだったのでしょうか.ag以前にあった全文検索系ツールを調べてみます.
ag(1) – The Silver Searcher. Like ack, but faster.
Recursively search for PATTERN in PATH. Like grep or ack, but faster.
https://github.com/ggreer/the_silver_searcher/blob/master/doc/ag.1.md
agはackやgrepの代替となることをdocumentで宣言しています.速さの他に,ackやgrepと比べてどのようなメリットがあるのでしょう.
It started off as a clone of Ack, but their feature sets have since diverged slightly.
Ackのクローンとして始まって,より沢山の機能が積まれるようになったようです.
https://shoyan.github.io/blog/2015/10/28/highway-faster-than-ag/ では,agが開発された背景について触れられています.要約すると,
- grepは
.gitignoreなどを解釈しないため,使い勝手が悪い. - ackは
.gitignoreなどを解釈し,デフォルトでディレクトリを再帰的に検索でき,ファイルタイプを指定可能で,検索結果をファイル単位でまとめて表示できる. - ackはperl製で速度に限界がある.
- agは高速なackを目指して開発された.
agはCで書かれているので,速度の面では圧倒的に優位ですね. さて,agにも欠点があり,EUC-JPやSJIS対応が不十分であったり,検索結果の出力順序が変わったりします.
| grep | ack | ag | |
|---|---|---|---|
| 速度 | 基準 | 比較的遅い? | 比較的速い |
| 言語 | C | perl | C |
| ディレクトリを再帰的に検索 | -rオプションが必要 |
デフォルトでする | デフォルトでする |
| ファイル種類を指定 | できない | できる | できる |
| ファイル種類を除外 | できない | できる | できる(名前ベース) |
| 独自のファイル種類を定義 | N/A | できる | できない |
| UTF-8/EUC-JP/SJISが混在した検索 | できない(1つのエンコーディングのみ) | できない(1つのエンコーディングのみ) | できない(1つのエンコーディングのみ) |
| 圧縮ファイル内の検索 | できない | できない | gz/xzで可 |
ripgrep
ポストagとして有名なのはripgrepでしょうか.ripgrepは以下の特長をアピールしています.
ただし,ripgrepには以下のような欠点があります.
ちなみにripgrepはrust製です.初めてrustプロダクトを見ました.
pt
一番気になっていたptについてはどうでしょう.agに対抗した感じのネーミングに好感度が上がります.
ptは以下の特長をアピールしています.
- UTF-8,EUC-JP,Shift_JISを検索できる.
- マルチプラットフォームで動くバイナリを提供できる.
ちなみにptはgo製です.goなのでシングルバイナリが生成できますね.
ripgrepが主張する特長をカバーできているか確認してみます.
ripgrepの欠点をカバーするかどうかについてはどうでしょう.動かして確認しました.
まとめ
いくつか欲しい機能もあわせて比較しました.
| grep | ack | ag | ripgrep(rg) | pt | |
|---|---|---|---|---|---|
| 速度 | 基準 | 比較的遅い? | 比較的速い | 速い | ag並み |
| 言語 | C | perl | C | Rust | Go |
| ディレクトリを再帰的に検索 | -rオプションが必要 |
デフォルトでする | デフォルトでする | デフォルトでする | デフォルトでする |
| ファイル種類を指定 | できない | できる(shebangも読める) | できる | できる | できる |
| ファイル種類を除外 | できない | できる | できる | できる | できる |
| 独自のファイル種類を定義 | N/A | できる | できない | できる | できない |
| UTF-8/EUC-JP/SJISが混在した検索 | できない(1つのエンコーディングのみ) | できない(1つのエンコーディングのみ) | できない(1つのエンコーディングのみ) | できる | できる |
| 圧縮ファイル内の検索 | できない | できない | gz/xzで可 | できない | できない |
| 出力桁数の制限 | できない | できない | -W/--widthオプション |
-M/max-columnsオプション |
できない |
| バックリファレンス | できる | できる | できる | できない | できない |
| 先/後読み | -Pオプションで可 |
できる | できる | できない | できない |
| マッチした前後行の表示 | -A/-B/-Cオプションで可 |
grepと同様 | grepと同様 | grepと同様 | grepと同様 |
| 順序が | 変わらない | 変わらない | 変わる | 変わる(-j1でシングルスレッドにすれば可) |
変わる |