第 11 章:複数ファイルの検索と置換
第 3 章では、現在のファイルにあるすべての foo を bar へ 置換する :%s/foo/bar/g を学びました。しかし実際のプロジェクトでは 「プロジェクト全体の foo をすべて bar に変える」ことが多く、単一ファイル用の :%s だけでは足りません。
この章では、検索と置換の範囲を「一つのファイル」から「複数のファイル」へ広げます。
複数ファイルを検索する
:vimgrep /pattern/ file...指定ファイル内でパターンを検索し、結果を quickfix リストへ格納:vimgrep /pattern/g **/*.js現在のディレクトリと全サブディレクトリにある.jsファイルを検索:grep pattern file...外部の grep プログラムで検索(高速だがシステムに依存)
** はすべてのサブディレクトリへ再帰的に一致し、*.js は指定した拡張子に一致 します。組み合わせると「あらゆる階層の js ファイル」を意味します。
注意::vimgrep は Vim の組み込み実装で、クロスプラットフォームですが低速です。 :grep は外部ツールに依存し、grepprg で rg や ag のような高速検索ツールを 設定できます。ファイルが多い場合は :grep を優先してください。
quickfix リスト
上の検索結果は quickfix というリストへ保存されます。これは Vim で複数ファイル を操作するときの中心となる仕組みです。
:copenquickfix ウィンドウを開く(一致一覧を表示し、Enter で該当位置へ移動):cclosequickfix ウィンドウを閉じる:cnext(省略形:cn)次の一致へ移動:cprev(省略形:cp)前の一致へ移動:cfirst/:clast最初 / 最後の一致へ移動:cc <N>N 番目の一致へ移動
このチュートリアル自身を検索してみましょう(読み取りだけなので安全です)。 Vim の作業ディレクトリが
ja/であることを確認し、:vimgrep /Vim/g *.md、:copenの順に実行します。:cn/:cpで一致箇所を移動してください。
一括置換
quickfix リストを使うと、リスト内の各項目に対してコマンドを一括実行できます。
:cdo {cmd}quickfix の各一致項目で cmd を実行:cfdo {cmd}quickfix の各ファイルで cmd を実行
典型的な複数ファイル置換は、まず vimgrep、次に cdo で置換します。
:vimgrep /foo/g **/*.js
:cdo s/foo/bar/g | update- 1 行目は
fooを含むすべての位置を検索し、quickfix へ格納 - 2 行目は各項目で置換を実行し、
| updateでファイルを保存
注意:s/foo/bar/g の後ろにある | update は重要です。付けない場合、変更は メモリ内だけにあり、ディスクへ書き込まれません。一つずつ確認するなら g を gc(confirm)へ変えると、Vim が置換のたびに確認します。
引数リスト
quickfix のほかに、処理対象ファイルを明示するのに適した「引数リスト」もあります。
:args **/*.js一致するファイルを引数リストへ追加:args現在の引数リストを表示:argdo {cmd}引数リスト内の各ファイルで cmd を実行
プロジェクト全体の置換は、次のようにも実行できます。
:args **/*.js
:argdo %s/foo/bar/g | update:argdo と :cdo の違いは対象範囲です。:argdo は「指定したファイル群」、 :cdo は「直前の検索で一致した具体的な位置」を対象にします。
練習時の注意:
:cdo/:argdoの一括置換は、破棄してよい一時ディレクトリ で試し、実際のプロジェクトで直接練習しないでください。変更前にgit commitまたはバックアップを行いましょう。Vim の一括置換は本当にすべてを書き換えます。
以上です。カーソル移動から複数ファイルの一括操作まで、この 11 章で日常的に使う Vim の技術の大部分を扱いました。Vim で問題に遭遇した場合や、よく使う操作が チュートリアルに足りない場合は、issues でお知らせください。 できる限り回答し、チュートリアルへ追加します。
ご覧いただきありがとうございます。気に入ったら、ぜひ共有してください。 Love life, love VIM!