この記事では、Vim / neovim の便利な機能である vimgrep と OSコマンドの grep の違いについて、ご紹介します。
[解答] 機能のvimgrep / 速度のgrep
Vim / neovim は、全文検索コマンドとして vimgrep と grep を実装しています。そのため、vimgrep コマンドを内部grep、grepコマンドを外部grepと呼びます。/ または ? で始める検索は、検索コマンドと呼ぶことで差別化します。
内部grep = Vimgrep
次の書式で実行することができます。
(ノーマルモード) :vimgrep {検索パターン} {検索対象} :vim {検索パターン} {検索対象}
Vim標準機能として実装しているExコマンドで、内部grep とも呼ばれます。
Vimさえ動作すれば利用できる反面、ファイルをすべてメモリに読み込むために動作速度は劣ります。
外部grep = grep
(ノーマルモード) :grep {検索パターン} {検索対象} :gr {検索パターン} {検索対象}
OS機能として実装している grep コマンドを活用するExコマンドで、外部grep とも呼ばれます。
良くも悪くも、次のコマンド実行しているだけです。
:!grep -n $* /dev/null {検索パターン} {検索対象} (Linux/Macの場合) :!findstr /n {検索パターン} {検索対象} (Windowsの場合)
そのため、OSコマンドとしての grep の引数などがそのまま利用可能です。
こちらは 内部grep よりも高速動作するのが利点と言えますが、実行可否や内容が環境依存となります。
内部grep VS 外部grep
次のような違いがあります。
比較軸 | 検索コマンド | 内部grep | 外部grep |
---|---|---|---|
実行速度 | 普通 | 普通 | 高速 |
対象 | カレントバッファのみ | ファイル(パス) 圧縮ファイル※ リモートファイル※ Git※ | ファイル(パス) |
日本語パス | OK | OK | 環境依存 |
エンコーディング認識 | 自動 | 自動 | 環境依存 |
改行コード認識 | 自動 | 自動 | 環境依存 |
検索パターン | Vim検索パターン (複数行可) | Vim検索パターン (複数行可) | コマンド依存 |
検索結果 | 該当行のみ | Quickfix / location ウインドウ表示可 | Quickfix / location ウインドウ表示可 |
ヒット件数 | 表示なし | 表示あり | 表示あり |
日本語テキスト | OK | OK | 環境依存 |
正規表現 | 利用可能 | 利用可能 | 利用可能 (引数次第) |
ヒット箇所の移動 | n / N | cn / cN | – |
※利用するプラグイン次第
大量のファイルで検索したいのでなければ vimgrep が便利だと思いますが、OSの grep コマンドに慣れているかによっても差が出るので、どちらが良いとは必ずしも言えません。
利用場面に応じて、使い分けたいところです。
補足
外部grep で利用するコマンドは grepprgオプションで設定しているものを利用します。
grepprg=grep -n $* /dev/null (Linux/Macの場合) grepprg=findstr\ /n (Windowsの場合)
こちらを任意のコマンドに変更することもできます。あるいは、外部grepを実行すると、内部grep (vimgrep) を実行させることもできます。
set grepprg=internal
このVimコマンドの補足情報
- 利用頻度
- 便利さ
- 覚え易さ
関連するVimヘルプ
Vim のヘルプでは下記のように解説されています。
Vimにはパターンを検索する方法が2つある: 内部grepと外部grepである。内部grepの利
点は、全てのシステム上で動作し、Vimの強力な検索パターンを使えることである。内
部grepが目的に合わない場合は外部grepを使うことができる。内部grepはファイルをメモリに読み込むため、より遅い。利点は:
– ファイルを開くときと同様に改行コードとエンコーディングが自動的に認識される。
– Vimの検索パターンを使う。複数行にわたるパターンが使える。
– プラグインが有効になっていれば、圧縮ファイル、リモートファイルを検索できる。
gzipnetrwこれを行うために、Vimは各ファイルを編集するときと同じように読み込む。そのファ
quickfix – Vim日本語ドキュメント
イルにマッチがなかったら、そのバッファは消去 (wiped out) される。多数のファイ
ルを扱うときのメモリ不足やファイル記述子不足を避けるために、ここではオプショ
ン ‘hidden’ は無視される。しかし、コマンド修飾子:hideが使われたときは、バッ
ファが読み込まれたままになる。これによって、同じファイルを続けて検索するのがと
ても高速になる。
:vim :vimgrep E682 E683
:vim[grep][!] /{pattern}/[g][j] {file} …
ファイル{file}から{pattern}を検索し、マッチ位置をエラー
リストに追加する。‘wildignore’ にマッチしたファイルは
無視される。‘suffixes’ にマッチしたファイルは最後に検
索される。
フラグ ‘g’ がない場合、各行は1度だけ追加される。
‘g’ がある場合、マッチ位置が毎回追加される。{pattern}はVimの検索パターンである。/ で囲まない場合、
それが{pattern}中に現れない限り、どんな非ID文字
(‘isident’ を参照) でも使える。
‘ignorecase’ が適用される。パターン中に/\cを含めると
大文字小文字を区別しなくなり、/\Cを含めると区別する
ようになる。これは ‘ignorecase’ より優先される。
‘smartcase’ は適用されない。
{pattern} が空のときは(つまり // が指定されたときは)、
最後に使われた検索パターンが使用される。last-pattern
:{count}vim[grep] …
このコマンドの前に数字が置かれると、その数が検索する
マッチの最大数となる。”:1vimgrep pattern file” とする
と最初のマッチだけを検索する。マッチが存在するかどうか
だけをチェックしたく、それが見つかったらすぐに終了して
ほしい場合に便利である。フラグ ‘j’ がない場合、最初のマッチへジャンプする。
‘j’ がある場合はquickfixリストが更新されるだけである。
[!]がついた場合、カレントバッファに対する変更は全て失われる。進行状況を示すため、1秒程度ごとに検索されたファイル名
quickfix – Vim日本語ドキュメント
が表示される。
例:
:vimgrep /an error/ *.c
:vimgrep /\<FileName\>/ *.h include/*
:vimgrep /myfunc/ **/*.c
“**” の使い方についてはstarstar-wildcardを参照。
5.2 外部grep
Vimはコンパイラに対するのと同じ方法 (:make参照) で “grep” やGNU id-utilsなどの
grepライクなプログラムと連携できる。(略):gr:grep
quickfix – Vim日本語ドキュメント
:gr[ep][!] [arguments] “:make” と同じようにしかし ‘makeprg’ の代わりに
‘grepprg’ が、‘errorformat’ の代わりに ‘grepformat’ が
使われる。‘grepprg’ が “internal” の場合、:vimgrepと
同様に機能する。その場合、パターンが区切り文字で囲まれ
ていなければならないことに注意。
プログラム出力のエンコーディングが ‘encoding’ と異なる
場合には、‘makeencoding’ オプションでエンコーディング
を指定できる。
こちらは、Vim上では下記のコマンドでヘルプを確認できます。
:help grep :help lid :help :vimgrep :help :vim :help :gr :help :grep
ヘルプで検索するときは、通常は大文字小文字は識別されませんので、どちらでも構いません。
参考書籍
こちらの書籍が参考になります。
Vim/neovim関連の書籍で、もっとも評判が良くてバイブルと呼んでる人もいる一冊です。Vim/neovimのバージョンに依存しない沢山のTips形式で、その表題通りに「思考のスピードで編集」できるようになるノウハウが詰まっています。その高い評価は Amazon のレビューからも分かる通りです。Vimmer なら必ず一度は読んでおいて間違いありません。
こちらもVim関連の書籍で評価が高い書籍の一冊です。vim-jpで見かける上級Vimmer(Vimサポーターズ)の皆様による、Vimを実践で使ったノウハウからプラグイン関連の情報が詰まっています。日本の Vim界隈を知る上でも是非一読しておきたい一冊です。
Vim/neovim の設定ファイルやプラグインなど、Vim script に関するノウハウがいくつも詰まった一冊です。日本で Vim Script をここまで深く解説している唯一の書籍と言えます。Vim力を伸ばしたいと考えるなら、絶対に避けては通れない書籍でしょう。