数多くあるUnixコマンドの中でも、もっとも利用頻度の高いもののひとつがgrepではないでしょうか。設定ファイルやログから該当する箇所を調べたり、ソースコードを検索したり、あるいはパイプラインのフィルタとして利用したりと、あらゆる場面で活躍する超基本ツールです。
とはいえgrepは機能がシンプル過ぎるため、もう少し空気を読んだ、賢い検索をしてくれる代替ツールもまた数多く存在します。たとえば本連載287回 ではThe Silver Searcher(ag)を紹介しました。
とはいえこれはもう6年も前の記事です。ag以降も、いろいろな検索ツールが登場しています。そこで今回はさらに高速な検索ツールである、ripgrepを紹介します。
ripgrepとは
ripgrepとは、公式サイト によると「ripgrep recursively searches directories for a regex pattern」だそうです。日本語にすると「正規表現でディレクトリを再帰的に検索できるツール」でしょうか。シンプルですね。
同サイトによると、「 ripgrepを使うべき理由」として、以下のような理由が挙げられています。
検索ツールとして必要なほとんどの機能が含まれており、他のツールの大抵のユースケースを置き換えることができる。
デフォルトでディレクトリを再起的に検索する。.gitignoreを見て不要なファイルを除外し、隠しファイルやバイナリは無視する。
検索対象を特定のファイルタイプに限定して検索できる。カスタムマッチングルールを使えば、新しいファイルタイプにも対応できる。
複数パターンの検索、色つきの強調表示、Unicodeの完全なサポートといった豊富な機能がある。
Unicodeをサポートしながらも高速である。
正規表現エンジンニPCRE2を使用できる。これにより正規表現の先読み、後読み、後方参照が利用できる。
EUC-JPやShift-JISをサポートしている。
gzip、bzip2、xzなどの圧縮ファイルの中からも検索できる。
様々な前処理フィルタをサポートしている。これによってPDFやサポート外の圧縮ファイルなどにも対応できる。
agと同じく「多機能で高速なgrep」を目指しているのがわかりますね。それでは実際に使ってみましょう。
ripgrepのインストール
Ubuntu 19.04であればリポジトリにパッケージが用意されていますので、APTでインストールが可能です。
aptコマンドでripgrepをインストール(Ubuntu 19.04以降)
$ sudo apt install ripgrep
また、ripgrepはsnapにもパッケージが用意されています。
snapでripgrepをインストール
$ sudo snap install ripgrep --classic
本記事執筆時点(2019年7月18日)で、Ubuntu 19.04のリポジトリにあるバージョンは0.10.0、snapにあるバージョンは11.0.1となっています[1] 。最新リリースが使いたい場合や、OSにUbuntu 18.04 LTSを使っている場合はsnapを使うとよいでしょう。
ripgrepを使ってみる
ripgrepの実行コマンド名は「rg」です。以下のように引数としてオプション、検索パターン、検索対象を指定して実行します。検索対象を省略した場合は、カレントディレクトリが対象となります。
ripgrepのコマンドの書式
$ rg [OPTIONS] PATTERN [PATH ...]
見ての通り、使い方はagなどの先行プロダクトに倣っているため、それらの使用経験があれば戸惑うことはないでしょう。また当然ですが、パイプで標準入力からデータを流し込み、フィルタとして使うこともできます。
「–help」オプションでヘルプが表示されるため、最初に軽く目を通しておきましょう。とはいえ、主要なオプションはどれもどこかで見たようなものばかりです。例をあげると、以下のようなものがあります。
マッチしたファイル名のみを表示する「-l」オプション。
大文字小文字の区別をしない「-i」オプション、逆に区別する「-s」オプション[2] 。
マッチした行の前後行も表示する「-A」「 -B」オプション。
ファイルごとに、マッチした件数を表示する「-c」オプション。
隠しファイルを検索対象にする「–hidden」オプション。
「-t」オプションを使うと、特定のファイルタイプに検索対象を限定できます。オプション引数に対象としたいファイルタイプを指定して使います。たとえば
Markdownファイルに検索対象を限定する例
$ rg -tmd PATTERN
とすることで、カレントディレクトリ以下のMarkdownファイル(拡張子がmarkdown、md、mdown、mkdnのもの)のみが検索対象となります。また「–type-list」オプションを指定すると、対応しているファイルタイプの一覧が確認できます。
Emacsからripgrepを使う
どのようなツールであっても、端末の中でしか使えないのでは不便です。特にripgrepはテキストを検索するためのツールですから、テキストエディタ上で使えれば便利だと誰もが思うことでしょう。そう、つまり人類にはEmacsからripgrepを呼び出すインターフェイスが必要だということです。
ripgrep.el
ripgrepのEmacsフロントエンドとしては、まずripgrep.el が挙げられます。パッケージはMEPLAにありますので、以下のようにMELPAのリポジトリを追加した上で「M-x package-install ripgrep」でインストールしてください。
~/.emacs.d/init.elにMELPAの設定を追加する
(require 'package)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
「M-x ripgrep-regexp」でripgrepによる検索を開始します。ミニバッファに「Ripgrep search for:」と表示されますので、検索したいパターンを入力します。続いて検索対象とするディレクトリを聞いてきますので、ディレクトリへのパスを入力してください。この際、デフォルトで「現在開いているバッファのファイルが存在するディレクトリ」が指定されています。
検索結果は「*ripgrep-search*」バッファに表示されます。このバッファ上で検索結果の行にカーソルを合わせてEnterを押すと、該当箇所へジャンプできます。この説明からわかるように、agのEmacsフロントエンドである「ag.el」とほぼ同じ使い勝手となっています。
図1 ripgrep.elで検索してみた例。ウィンドウが分割され、検索結果の*ripgrep-search*バッファが下部に表示される。
rg.el
ripgrepのEmacsフロントエンドにはもうひとつ、rg.el という実装が存在します。こちらもMELPAにパッケージがありますので、ripgrep.el同様に「M-x package-install rg」でインストールできます。
「M-x rg」で検索を開始します。使い方はripgrep.elとおおむね同じですが、rg.elでは検索時にファイルタイプを指定できます。検索したいパターンを入力した後、ミニバッファに「Search in files:」と表示されますので、対象としたいファイルタイプを指定してください。デフォルトでは現在バッファに開いているファイルタイプが指定されています。
「M-x rg-enable-default-bindings」を実行すると、rg.elの機能を呼び出すプレフィックスキーを有効にできます。デフォルトのプレフィックスキーは「C-c s」に設定されています。こうしておけば「C-c s r」でrgを呼べるため、Emacs上で頻繁にripgrepを使うのであれば便利な機能です。
テキスト以外のファイルからも検索する
ripgrepは便利で高速ですが、あくまでテキストファイルからgrepするツールであることには変わりありません。どうせならPDFなど、テキスト以外のファイルもまとめて検索できたら便利ですよね。
そうしたテキスト以外のファイルからもgrepしようというripgrepのフロントエンドが、ripgrep-all(rga) です。rgaではPDF、docx、sqliteデータベース、epub、mp4動画の字幕などからテキストを検索できます。
rgaはパッケージが提供されていないため、依存するパッケージをインストールした上で[3] 、「 rga」と「rga-preproc」のふたつの実行ファイルをパスの通った場所にコピーしてください。
依存パッケージをインストールする
$ sudo apt install pandoc poppler-utils ffmpeg cargo
GitHubのリリースページからバイナリをダウンロードして、~/binディレクトリにコピーする
$ curl -L -O https://github.com/phiresky/ripgrep-all/releases/download/0.9.2/ripgrep_all-0.9.2-x86_64-unknown-linux-musl.tar.gz
$ tar xf ripgrep_all-0.9.2-x86_64-unknown-linux-musl.tar.gz
$ cd ripgrep_all-0.9.2-x86_64-unknown-linux-musl
$ cp rga rga-preproc ~/bin
rgaコマンドも、オプション、検索パターン、対象ディレクトリを指定して実行します[4] 。
図2 rgaで検索してみた例。PDFやepubからも日本語での検索が可能。PDFの場合はページ番号も表示される
「rga –rga-list-adapters」で、対応しているアダプターを確認できます。また「rga –help」でrgaのヘルプを確認できます。詳細な使い方はこちらを参照してください。