:substituteコマンド活用集 全置換・行頭行末への挿入・確認付き置換
:s///の基本形は知っていても、行頭に文字列を追加したいときや、置換前に1件ずつ確認したいときにどう書けばいいか毎回思い出せません。よく使うパターンをまとめて手元に置いておきます。
目次(10項目)
| パターン | これだけ覚える |
|---|---|
:%s/foo/bar/g | ファイル全体を一括置換 |
:%s/^/# /g | 全行の行頭に文字列を追加 |
:%s/$/;/g | 全行の行末に文字列を追加 |
:%s/foo/bar/gc | 1件ずつ確認しながら置換 |
基本形
:[range]s[ubstitute]/{pattern}/{string}/[flags]
rangeを省略すると現在行だけが対象になります。ファイル全体を対象にしたいときは%を先頭に付けます。
1. ファイル全体を一括置換する
:%s/foo/bar/g
%で全行、gフラグで1行内の複数マッチもすべて対象にします。gを付けないと各行の最初のマッチだけが置換される点に注意してください。
2. 全行の行頭に文字列を追加する
foo = 1 bar = 2 baz = 3
:%s/^/# /g# foo = 1 # bar = 2 # baz = 3
マッチパターンを行頭を表す^にすると、何も消さずに指定した文字列だけを挿入できます。コメントアウトしたい行をまとめて選んでこのパターンを使えば、一括コメントアウトになります。
3. 全行の行末に文字列を追加する
:%s/$/;/g
行末を表す$を使えば、同じ要領で行末に文字列を追加できます。CSVの各行にカンマを補いたい、SQLの各行にセミコロンを付けたい、といった場面で使います。
4. 1件ずつ確認しながら置換する
:%s/foo/bar/gc
cフラグを付けると、マッチするたびに置換するかどうかを聞かれます。一括置換に自信が持てないときは、まずc付きで試すと事故を防げます。
| キー | 動作 |
|---|---|
| y | この箇所を置換する |
| n | この箇所をスキップする |
| a | 残り全部を置換する |
| q | 確認を終了する |
置換後の文字列に検索結果を埋め込む
:%s/\(\d\+\)/[\1]/g " 数字を角括弧で囲む
\(...\)でグループ化した部分は、置換後の文字列側で\1のように参照できます。マッチした内容の一部を活かしたまま前後に文字を足したいときは、パターン全体を消して打ち直すのではなく、グループ参照を使うと効率的です。
範囲を限定したいとき
:5,10s/foo/bar/g " 5〜10行目だけを対象にする
ビジュアルモードで範囲を選択してから:を押すと:'<,'>s/が自動的に入力され、選択した範囲だけを対象にできます。
cで確認しながら置換。基本形さえ覚えれば、あとはパターンとフラグの組み合わせでほとんどのケースに対応できます。
複数行にまたがるSQLの末尾にカンマを付け忘れて何度もやり直した経験から、:%s/$/,/gで行末挿入をまとめて済ませる癖がつきました。範囲を間違えて余計な行まで置換してしまった苦い経験もあり、それ以来ファイル全体に影響する置換は必ずcフラグを付けて確認するようにしています。
大文字小文字を区別する・しないを切り替える
:%s/foo/bar/gi " 大文字小文字を区別しない
:%s/foo/bar/gI " 大文字小文字を区別する
'ignorecase'を設定していない環境ではデフォルトで大文字小文字が区別されますが、iフラグを付ければ一時的に区別なしで検索できます。逆に'ignorecase'を常時オンにしている環境では、特定の置換だけ厳密に区別したい場合にIフラグが使えます。
単語の境界を厳密に指定したいときは、パターン側に単語境界の指定を加えると便利です。
:%s/\<foo\>/bar/g " "foo"という単語だけにマッチ(fooobarのような部分一致を除外)
\</\>はそれぞれ単語の先頭・末尾の境界を表します。foobarのような文字列の一部にfooが含まれていても誤ってマッチしないようにしたいときに使います。
選択範囲だけを対象にする
:'<,'>s/foo/bar/g
ビジュアルモードで対象範囲を選択してからコマンドラインに入ると:'<,'>が自動的に補われます。ファイル全体ではなく一部の行だけに置換をかけたいときは、行番号を数えるより範囲選択してから:を押したほうが確実です。
まとめ
:substituteは^/$による位置指定とcフラグによる確認だけ覚えておけば、日常的な置換作業の大半をカバーできます。最短マッチが必要な複雑なパターンは別記事を参照してください。行内だけで済む書き換えなら行内の置換4パターンのほうが手数が少なく済みます。