Home > Vim Hacks > Hack #113: grex – 特定パターンにマッチする行をまとめて取り扱う

Hack #113: grex – 特定パターンにマッチする行をまとめて取り扱う

問題

Vimで大量のデータを取り扱う場合、 特にCSVなどの1レコード1行の形式のデータを取り扱うとき、 特定の条件にマッチする行を抽出するなど、 まとめて編集したいことがしばしばあります。

例えばバッファの内容が以下のようになっていたとします:

Name      Creator            First release Cost License          Open source
Diakonos  Pistos             2004          Free MIT              Yes
GNU Emacs Richard Stallman   1984          Free GPL              Yes
JED       John E. Davis      1992          Free GPL              Yes
Metapad   Alexander Davidson 1999          Free GPL              Yes
Notepad   Microsoft          1985          -    Proprietary      No
RText     Fifesoft           2003          Free GPL              Yes
SciTE     Neil Hodgson       1999          Free HPND             Yes
Vim       Bram Moolenaar     1991          Free GPL - compatible Yes
Yi        Don Stewart        2005          Free GPL              Yes

この中から 「19XX年にリリースされたエディタ(に対応する行)を削除する」 としましょう。 これは:globalを利用して行うことができます (:g/\<19\d\d>/d)。

では 「19XX年にリリースされたエディタ(に対応する行)をヤンクする」 としたらどうでしょうか。 すぐに思いつくのは:g/\<19\d\d>/yですが、 これはマッチする行で毎回ヤンクを行うため、 レジスタに残るのは最後にマッチした行のテキストだけになります。 つまり、ヤンクしたいテキストは以下の通りなのですが、

GNU Emacs Richard Stallman   1984          Free GPL              Yes
JED       John E. Davis      1992          Free GPL              Yes
Metapad   Alexander Davidson 1999          Free GPL              Yes
Notepad   Microsoft          1985          -    Proprietary      No
SciTE     Neil Hodgson       1999          Free HPND             Yes
Vim       Bram Moolenaar     1991          Free GPL - compatible Yes

実際にヤンクされるのは以下の1行だけになります。

Vim       Bram Moolenaar     1991          Free GPL - compatible Yes

この観点で考えると、最初の「削除」についても同様のことが言えます。 つまり、削除されたテキストを別の箇所にペーストした場合、 ペーストされるのは最後にマッチした行のテキストだけになります。

上記のように、特定パターンにマッチする行をまとめて削除/ヤンクして ペーストするにはどうすればよいでしょうか。

解決方法

ベタな解決方法としては、 削除/ヤンクされるテキストをレジスタに上書きするのではなく、 レジスタに追加するようにします。 これには"A-"Zなどの大文字のレジスタを使います。

例えば:g/{pattern}/y Aとすると、 "aレジスタにマッチする各行のテキストが追記されるので、 "ap (操作直後であればpだけ)で 各行のテキストを一度にペーストできます。

ところが既に"aに何か別のテキストが入っていた場合、 それに対してテキストが追加されていくため、 実際には:let @a = ''などとして 操作前にレジスタの内容を空にする必要があります。 これは結構面倒です。

幸いなことに、上記のような操作パターンをまとめたコマンドを提供する grex というプラグインがありますので、これを使うと簡単に行うことができます。

例えば特定パターンにマッチする行をまとめて削除する場合、 /\<19\d\d>などとしてマッチするかどうかを確認した後、 :Gredで行うことができます。 ヤンクであれば:Greyで行うことができます。

なお、各コマンドは:g/{pattern}/[cmd]と 同様の形式では実行できません。 これは通常の操作では 検索パターンを含むコマンドを一度に入力して実行することはなく、 ('incsearch'および'hlsearch'を有効にした上で)/{pattern}により 期待通りの検索パターンができたかどうかをインタラクティブに確認してから 実際のコマンドを入力・実行することがほとんどだからです。

参考資料

kana
このエントリーをはてなブックマークに追加
はてなブックマーク - Hack #113: grex – 特定パターンにマッチする行をまとめて取り扱う
Share on Facebook
Post to Google Buzz
Bookmark this on Google Bookmarks
Bookmark this on Yahoo Bookmark
Bookmark this on Livedoor Clip
Share on FriendFeed

Comments:0

Comment Form
Remember personal info

Trackbacks:0

Trackback URL for this entry
http://vim-users.jp/2009/12/hack113/trackback/
Listed below are links to weblogs that reference
Hack #113: grex – 特定パターンにマッチする行をまとめて取り扱う from Vim-users.jp

Home > Vim Hacks > Hack #113: grex – 特定パターンにマッチする行をまとめて取り扱う

Search
Feeds
Links
  • 公式
  • 勉強会
  • 情報
  • コミュニティ
  • Meta
    Etc
    Creative Commons License
    This blog is licensed under a Creative Commons License.

    Return to page top