Skip to content

第 11 章:複数ファイルの検索と置換

第 3 章では、現在のファイルにあるすべての foobar へ 置換する :%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 は外部ツールに依存し、grepprgrgag のような高速検索ツールを 設定できます。ファイルが多い場合は :grep を優先してください。

quickfix リスト

上の検索結果は quickfix というリストへ保存されます。これは Vim で複数ファイル を操作するときの中心となる仕組みです。

  • :copen quickfix ウィンドウを開く(一致一覧を表示し、Enter で該当位置へ移動)
  • :cclose quickfix ウィンドウを閉じる
  • :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 で置換します。

vim
:vimgrep /foo/g **/*.js
:cdo s/foo/bar/g | update
  • 1 行目は foo を含むすべての位置を検索し、quickfix へ格納
  • 2 行目は各項目で置換を実行し、| update でファイルを保存

注意:s/foo/bar/g の後ろにある | update は重要です。付けない場合、変更は メモリ内だけにあり、ディスクへ書き込まれません。一つずつ確認するなら ggc(confirm)へ変えると、Vim が置換のたびに確認します。

引数リスト

quickfix のほかに、処理対象ファイルを明示するのに適した「引数リスト」もあります。

  • :args **/*.js 一致するファイルを引数リストへ追加
  • :args 現在の引数リストを表示
  • :argdo {cmd} 引数リスト内の各ファイルで cmd を実行

プロジェクト全体の置換は、次のようにも実行できます。

vim
: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!