← Vim道場

条件に合う行だけ処理する

「TODO と書いてある行だけ全部消したい」「ログ行だけ書き換えたい」。こういう「条件に合う行だけ」の処理をまとめて行うのがグローバルコマンドです。置換が「文字列を探して直す」なら、こちらは「行を探して処理する」道具です。

第6章 まとめて片づけるレッスン 28 / 36

:s との違い

:%s は「文字列を探して置き換える」もので、対象は文字列です。:g は「行を探して、その行に対してコマンドを実行する」もので、対象は行です。

だから :g/debug/d は「debug を含む行を消す」になります。:%s/debug// だと debug という文字だけが消えて、行そのものは空行として残ります。消したいのが行なのか文字なのかで使い分けます。

組み合わせると効く

本物のVimでは、実行するコマンドに normal を指定して普通のキー操作も流せます。:g/TODO/normal A ; のように書くと、TODO を含む行すべての末尾に文字を足せます(この練習ページでは ds だけを扱っています)。

範囲を絞ることもできて、:1,20g/foo/d なら1行目から20行目までが対象です。何も書かなければファイル全体が対象になります。

実行する前に確かめる

対象が広いので、間違えると一気に消えます。不安なときは先に / で同じパターンを検索して、どの行に当たるかを目で確かめてから実行すると安全です。

実行してしまっても u で元に戻せます。グローバルコマンド1回ぶんがまとめて1つの変更として扱われるので、u を1回押せば全部戻ります。

:v は条件を裏返す

:v:g! の別名で、パターンに一致しない行を対象にします。:v/^#/d なら、# で始まらない行、つまりコメント以外を全部消します。

ログから特定の種類の行だけを残したいときは、残したいものを :v で指定するほうが短く書けます。消したいものを列挙するか、残したいものを1つ指定するかで選んでください。

行を消すだけでなく集められる

実行するコマンドは ds だけではありません。:g/ERROR/t$ と書くと、一致した行をファイルの末尾に複製できます。:g/ERROR/y A なら、一致した行をレジスタ A に集められます。

大文字のレジスタが追記になる性質と組み合わせると、散らばった行を1か所に集めてから別のファイルへ貼る、という作業が2ステップで終わります。ログの調査でよく使われる形です。

先に印を付けてから実行している

:g は、まず条件に一致する行すべてに内部で印を付け、そのあとで印の付いた行に対してコマンドを実行します。2段階になっているので、実行中に行が増減しても対象がずれません。

この仕組みのおかげで :g/foo/d は行を消しながらでも取りこぼしません。1行ずつ上から処理していたら、消したぶんだけ行番号がずれて飛ばしてしまうところです。

このレッスンで扱うキー

キー動き
:g一致する行だけに実行
:v一致しない行だけに実行
d対象の行を削除
s対象の行を置換

関連記事

レッスン一覧へ戻るキーの逆引き一覧検定を受ける