fudist

ホーム‎ > ‎vim UTF-8日本語版‎ > ‎

vimのgrepの設定と使い方


vimやgvimでgrepを使用する方法は内部grep(vimgrep)と外部grepの2種類あります。

   長所  短所
 内部grep
 (vimgrep)  
 ・日本語や日本語pathも問題なく扱える。
 ・ファイルごとに文字エンコーディングが違っていても問題ない。
 ・vim/gvimさえ有れば実行可能。

 ・速度が外部grepに比べて非常に遅い。
 ・最後の編集位置などの履歴が消えてしまうことがある。
 これらは検索対象ファイル数が多くなるほど問題になる。

 外部grep
(GNU/cygwin grep等)
 速度がvimgrepに比べて圧倒的に速い。
 
 ・日本語や日本語pathの扱いに問題がある場合がある。
 ・ファイルごとに文字エンコーディングが違う時、特定の文字エンコーディングしか検索できない。
 ・(特にWindowsの場合は)別途grepが必要。
 ・utf-8のBOM付きの場合、最初の一文字が検索できない事がある。。


内部grep(vimgrep)は vimに普通のファイルとしてバッファに読み込んでから grep同等の処理を行っているため、速度の問題は対処しようがありません。
ファイルを読み込んだのと同じ処理が行われますので、2000ファイルがgrep対象になったら2000ファイル分のバッファを確保します。
大抵は問題有りませんが、vimgrepしただけで一部の動作やバッファ管理系などのプラグインが重くなる事もあります。

外部grep(GNU grep、cygwin grep、yagrep等)は、速度は圧倒的に速いのですが、日本語(全角文字)の扱いに若干問題が出てくる事があります。
たとえばcp932のファイルの「だめ文字」や、vimの内部エンコードと異なる文字エンコードの日本語ファイルを扱いたい場合などは、QFixGrepなどの日本語grepヘルパーが必要になります。
英数字しか使用しないなら全く問題はありません。
またBOM付きutf-8ファイルでは外部grepで最初の一文字が検索できないことがあります。
これはBOMが文字ではないバイト列としてファイルの先頭に埋め込まれているためで、正規表現で行頭を検索する場合などに問題となります。
Windowsの場合はメモ帳でutf-8のファイルを開いて保存すると強制的にBOM付きへ変換されてしまうので気をつける必要があります。

以下には、双方の設定と簡単な使い方、外部grepでの日本語の文字化け、Windowsの vim/gvimをUTF-8化した時などの外部grepの問題点について書かれています。


内部grep(vimgrep)の使い方

vim 7.0以降ならコマンドモードから vimgrep が使えます。
以下のように実行すると、"検索文字"をカレントディレクトリのtxtファイルから検索して、最初にマッチした行に移動します。
:vimgrep 検索文字 *.txt
最初にマッチした場所へ移動したくない場合は / で検索ワードを囲んで j オプションを指定します。
:vimgrep /検索文字/j *.txt
いずれにしても / 自身を検索したい場合は、/ をエスケープしてやる必要があります。
再帰検索を行いたい場合は、ファイル名を **/*.txt のように **/ 付で指定します。
:vimgrep 検索文字 **/*.txt
検索した後は :copen でQuickfixウィンドウを開いて、検索結果を一覧表示、選択が可能です。
Quickfixウィンドウを開かなくても :cp(cprev)、:cn(cnext) で前後の結果へジャンプできます。

検索後に自動でQuickfixウィンドウを開くには次のように実行します。
cw は cwinの略表記です。
:vimgrep 検索文字 *.txt |cw
また、次のように設定すれば、コマンドから grep と打ってもvimgrepが使用されます。
set grepprg=internal

外部grepの使い方

grepをコマンドプロンプト(shell)から使えるようにして、次のように.vimrcに設定すれば使用できるようになります。
set grepprg=grep\ -nH
unix系の場合はgrepがほぼ標準で入っているので、これで設定は終了です。

Windows用grepの入手場所と設定

 cygwin  http://www.cygwin.com
 GNU grep
 http://gnuwin32.sourceforge.net/packages/grep.htm
 yagrep  http://www.kt.rim.or.jp/~kbk/yagrep/

cygwinなどをインストールしていてコマンドプロンプトから grepが使える場合は、.vimrcで次のように指定します。

set grepprg=grep\ -nH
cygwingrep.zip に必要なファイルを抽出してあるので、vimと同じディレクトリか、pathの通った場所にコピーして使用する事も出来ます。
path を通していないなら、pathは環境に合わせてフルpathで指定して下さい。
set grepprg=c:/cygwin/bin/grep\ -nH
cygwin 1.7のgrepを抽出して使用する場合は、以下のページも参考にしてください。
http://d.hatena.ne.jp/fuenor/20090301/1235908129


yagrep を使用する場合もダウンロードして、vim/gvimの実行ファイルと同じフォルダにコピーすれば使用できるようになります。
set grepprg=yagrep\ -nH



外部grepの使い方

設定が済んだら、以下のように実行すると、"検索文字"をカレントディレクトリのtxtファイルから検索します。
:grep 検索文字 *.txt
検索した後は :copen でQuickfixウィンドウを開いて、検索結果を一覧表示、選択が可能です。
Quickfixウィンドウを開かなくても :cp(cprev)、:cn(cnext) で前後の結果へジャンプできます。
オプションについては、使用する各grepのマニュアルを参照して下さい。
再帰検索のオプションは大抵 -r です。
:grep -r 検索文字 *.txt
検索後に自動でQuickfixウィンドウを開くには次のように実行します。
cw は cwinの略表記です。
:grep 検索文字 *.txt |cw

ASCII文字(英数字)しか grep しないなら全く問題はありませんが、そうでないなら 外部grepの問題点 を参照してください。


外部grepの問題点

内部エンコードと異なる文字エンコードのファイルを扱う場合は日本語を外部grepで検索できません。
外部grepで内部エンコードと異なるファイルを日本語検索する場合やダメ文字を扱う場合、QFixGrepのような日本語対応のgrepヘルパーが必要になります。

特にWindows版vim/gvimの内部エンコードをutf-8化している場合は日本語ファイル名(path)にも気をつける必要があります。

Windows / Linux 共通の問題

  • utf-8のBOM付きの場合、最初の一文字が検索できない事がある。
    BOMは文字ではないバイト列としてファイルの先頭に埋め込まれているため、正規表現で行頭を検索する場合などは検索不可。
  • ucs2-leなどリトルエンディアンのファイルは検索できない。

Windowsの場合

Windowsでvim/gvimの内部エンコードを変更して、外部grepを使用した場合の問題点を表にまとめました。
Windowsでのデフォルト内部エンコードはcp932(Shift_JIS)です。

 内部エンコード
 日本語ファイル名  cp932のファイル  utf-8のファイル  eucのファイル
 cp932
 日本語も表示される
 ダメ文字以外の日本語検索は可  日本語検索不可  日本語検索不可
 utf-8  日本語部分の文字化け/指定不可  日本語検索不可
 日本語検索可
 日本語検索不可
  • 「日本語ファイル名」にはpathも含みます。
    指定不可はコマンドモードから日本語ファイル名(path)が指定できないだけなので、カレントディレクトリ以下のファイルしか検索しないなら問題はありません。
  • 日本語検索不可の場合、ASCII文字で検索することは可能ですが、日本語部分のgrep表示は文字化けしています。
  • Windowsのメモ帳でutf-8のファイルを保存すると、BOM付きに強制変換するので、最初の一文字が検索出来なくなる事があります。
具体的なダメ文字については「Shift_JIS(cp932)の「ダメ文字」」を参照して下さい。

Linux(Ubuntu)の場合

 内部エンコード
 日本語ファイル名  cp932のファイル  utf-8のファイル  eucのファイル
 utf-8  日本語も表示される  日本語検索不可
 日本語検索可
 日本語検索不可

shellと内部エンコードが基本的に一致しているので、問題はutf-8以外のファイルの日本語検索不可だけになります。
内部エンコードと異なるファイル(cp932等)を日本語検索する場合、nkf を使用して変換してやるか、QFixGrepのような日本語対応のgrepヘルパーを使用します。

結論

速度的に問題ないならvimgrepを使用します。
速度が問題の場合や、検索対象ファイル数が多くて重くなったり、最後の編集位置などを消されたくない場合は外部grepを使用します。

速度的な問題から外部grepを使用する場合で、うまく外部grepで扱えない事があるのは以下のような場合です。
以下のような場合はQFixGrepなど、何らかの日本語grepヘルパーなどが必要になります。

Windows(vimの内部エンコード cp932)の場合

  • cp932のファイルで「ダメ文字」を扱いたい場合
  • cp932以外のファイルを外部grepで日本語検索したい場合

Windows(vimの内部エンコード utf-8)の場合

  • 日本語を含むファイル名やpathが含まれている場合
  • utf-8以外のファイルを外部grepで日本語検索したい場合

Linux(Ubuntuでvimの内部エンコード utf-8)の場合

  • utf-8以外のファイルを外部grepで扱いたい場合