Next: , Previous: , Up: 目次   [Index]


便利な小技

*usr_12.txt*	For Vim バージョン 8.1.  Last change: 2017 Aug 11

		     VIM USER MANUAL - by Bram Moolenaar

				便利な小技

コマンドを組み合はせれば、ほとんど何でもこなすことができます。この章では、便利なコマンドの組み合はせをいくつか紹介します。今までに紹介したコマンドを主に使ひますが、まだ紹介してゐないコマンドも少し登場します。

|12.1|單語を置換する
|12.2|"Last, First" を "First Last" に變更する
|12.3|リストをソートする
|12.4|行を逆順に竝べ替へる
|12.5|單語を數へる
|12.6|マニュアルを引く
|12.7|空白を取り除く
|12.8|單語が使はれてゐる場所を檢索する

單語を置換する

置換コマンドを使ふと、文章中に現れる單語を別の單語に置換することができます:

:%s/four/4/g

"‘%’" はすべての行を處理するための範圍指定です。末尾の "‘g’" は、行のすべての單語を置換するための指定です。

上記のコマンドは正しく動作しません。例へば、"thirtyfour" といふ單語がファイルに含まれてゐた場合、"thirty4" に置換されてしまひます。これを防ぐには、"‘\<’" を使つて單語の先頭にヒットさせます:

:%s/\<four/4/g

これでもまだ、"fourteen" のやうな單語が閒違つて置換されてしまひます。"‘\>’" を使つて單語の末尾にヒットさせませう:

:%s/\<four\>/4/g

プログラムを書いてゐるなら、コメントの中にある "four" だけを置換したい場合もあるでせう。コメントの中かどうかを區別するのは難しいので、置換コマンドに "c" フラグを指定して、確認しながら置換してください:

:%s/\<four\>/4/gc

複數のファイル內で置換する

複數のファイル內で置換したい場合を考へます。ファイルを1つずつ開いて、その都度コマンドを入力することもできますが、操作の記錄と再實行を使へば、はるかに素早く置換できます。

擴張子が ".cpp" の C++ ファイルが入つたディレクトリがあるとします。"GetResp" といふ函數を "GetAnswer" に置換してみませう。

vim *.cppVim を起動して、すべての C++ ファイルを引數リストに加へる。Vim が起動すると、最初のファイルが表示されます。
qqレジスタ "q" に記錄を開始する。
:%s/\<GetResp\>/GetAnswer/g最初のファイルで置換コマンドを實行する。
:wnextファイルを保存し、次のファイルに移動する。
q記錄を終了する。
@qレジスタ "q" を實行する。置換コマンドと ":wnext" が再實行されます。エラーメッセージが表示されたりしないか確認してください。
999@qレジスタ "q" を繰り返し實行し、殘りのファイルをすべて處理します。

最後のファイルを處理したとき、もうそれ以上ファイルがないので、":wnext" コマンドがエラーメッセージを表示します。それにより、實行が中斷され、すべてが完了します。

Note:
記錄されたコマンドの實行中にエラーが發生すると、實行は中斷されます。ですから、エラーが出ないやうに注意して操作を記錄してください。

まだ問題が 1 つ殘つてゐます。もしも、"GetResp" を含んでゐないファイルがあつた場合、置換コマンドがエラーを發生し、そこで處理が停止してしまひます。それを避けるには、置換コマンドに "e" フラグを指定してください:

:%s/\<GetResp\>/GetAnswer/ge

"e" フラグは、パターンが見つからなくてもエラーを發生させないための指定です。

"Last, First" を "First Last" に變更する

次のやうな形式で名前の一覽があるとします:

Doe, John
Smith, Peter

これを次のやうに變更したいとします:

John Doe
Peter Smith

これはたつた 1 つのコマンドでできてしまひます:

:%s/\([^,]*\), \(.*\)/\2 \1/

1 つずつ說明しませう。これが置換コマンドであることはわかりますよね。"%" はすべての行を示す範圍指定です。つまり、ファイルのすべての行で置換が實行されます。

置換コマンドには "/from/to/" といふ形式で引數を指定します。スラッシュ (‘/’) は "from" パターンと "to" 文字列の區切りです。"from" パターンは次のやうになつてゐます:

\([^,]*\), \(.*\)
1 つ目の \( \) で圍まれた部分は "Last" です\(     \)
コンマ (,) 以外の文字が[^,]
何文字でもマッチする*
", " といふ文字にそのままマッチ,
2 つ目の \( \) で圍まれた部分は "First" です\(  \)
どんな文字でも.
何文字でもマッチする*

"to" の部分には "\2" と "\1" が指定されてゐます。これは後方參照といふものです。"\( \)" で圍まれた部分にマッチしたテキストを參照してゐます。"\2" は 2 つ目の "\( \)" で圍まれた部分にマッチしたテキスト ("First" name) を參照してゐます。"\1" は 1 つ目の "\( \)" ("Last" name) を參照してゐます。

置換コマンドの "to" 部分には最大で 9 個の後方參照を指定できます。"\0" はパターンがマッチしたテキスト全體になります。置換コマンドには他にもいくつか特殊なアイテムがあります。|sub-replace-special| を參照してください。

リストをソートする

Makefile ではよく、ファイルのリストが使はれます。例:

OBJS = \
    version.o \
    pch.o \
    getopt.o \
    util.o \
    getopt1.o \
    inp.o \
    patch.o \
    backup.o

このリストをソートするには、外部コマンドの sort を使つてテキストをフィルタリングします:

/^OBJS
j
:.,/^$/-1!sort

リストの先頭 (行頭が "OBJS" で始まる行) に移動してから、一行下に移動、その行から次の空行までの範圍をフィルタに通してゐます。ビジュアルモードで範圍を選擇してから "!sort" を實行する方法でも構ひません。その方が入力は簡單です。行がたくさんある場合は少し面倒かもしれませんが。

結果は、次のやうになります:

OBJS = \
    backup.o
    getopt.o \
    getopt1.o \
    inp.o \
    patch.o \
    pch.o \
    util.o \
    version.o \

各行の末尾に行結合のためのバックスラッシュ (\) が使はれてゐる點に注意して下さい。竝べ替へたために、これが壞れてしまひました。"backup.o" はリストの最後にあつたので行末にバックスラッシュが付いてゐませんでしたが、竝べ替へによつて別の場所に移動したため、バックスラッシュが必要になつたのです。

一番簡單な解決方法は "A \<Esc>" でバックスラッシュを追加することです。最後の行にあるバックスラッシュは次の行を空白行にしておけば削除しなくても問題ありません。これで同じ問題は二度と起きないでせう。

行を逆順に竝べ替へる

|:global| コマンドと |:move| コマンドを組み合せて、全ての行を 1 行目の上に移動することで、行を逆順に竝べ替へたファイルを作ることができます。コマンドは次の通りです:

:global/^/m 0

短縮して書くこともできます:

:g/^/m 0

"^" といふ正規表現は行の先頭に (それが空行であつても) マッチします。|:move| コマンドはマッチした行を 0 行目 (實際には存在しない假想的な行) の下に移動します。つまり、マッチした行がファイルの先頭行になります。|:global| コマンドは行番號が變更されても處理を繼續できます。そして、マッチしたすべての行が、順番にファイルの先頭に移動していきます。

ある一定の範圍だけ竝べ替へることもできます。まづ、竝べ替へたい範圍の 1 行上に移動し、"mt" でマークします。そして、範圍の末尾に移動し、次のやうに入力します:

:'t+1,.g/^/m 't

單語を數へる

ときには、單語數に制限のある文章を書かなければならない場合もあるでせう。Vim には單語を數へるための機能があります。

ファイル全體の單語數を數へるには、次のコマンドを使ひます:

g CTRL-G

"g" の後の空白は入力しないでください。この空白はコマンドを讀み易く表記するためのものです。

次のやうな結果が出力されます:

列 1 / 0; 行 141 / 157; 單語 748 / 774; バイト 4489 / 4976

これを見れば、何番目の單語 (748) にカーソルがあり、ファイル全體でいくつの單語 (774) があるのかがわかります。

ファイルの一部の文章についてのみ單語を數へたい場合は、テキストの先頭に移動して"g CTRL-G" を入力し、テキストの末尾に移動して "g CTRL-G" をもう一度入力し、そして、表示された單語の位置を引き算して單語數を求めます…これは頭の體操にはなりますが簡單な方法とは言へませんね。ビジュアルモードを使へば、テキストを選擇してから "g CTRL-G" を入力するだけです。次のやうな結果が表示されます:

選擇 5 / 293 行; 70 / 1884 單語; 359 / 10928 バイト

單語や行などを數へる他の方法については |count-items| を參照してください。

マニュアルを引く

シェルスクリプトや C プログラムを書いてゐるときに、コマンドや函數のマニュアルを引きたいことがあると思ひます (Unix での話です)。まづは簡單な方法でやつてみませう。ヘルプを引きたい單語の上にカーソルを移動して、次のコマンドを入力します:

K

單語を引數として "man" プログラムが實行され、マニュアルが見つかつた場合は、それが表示されます。テキストをスクロール表示するために、標準設定のページャ (おそらく "more" プログラム) が使はれます。マニュアルを最後まで表示したら、<Enter> を押して Vim に戾つてください。

この方法の缺點は編輯中のテキストとマニュアルを同時に表示できないことです。しかし、Vim ウィンドウの中にマニュアルを表示する方法もあります。最初に、man ファイルタイププラグインをロードしてください:

:runtime! ftplugin/man.vim

このコマンドを vimrc ファイルに書いておけばいつでも使へるやうになります。さて、":Man" コマンドが使へるやうになりました。新しいウィンドウにマニュアルを表示できます:

:Man csh

カラー表示されたテキストをスクロールして表示することができます。これで、調べたい說明を見つけることができますね。CTRL-W w を使へば、元のウィンドウにジャンプできます。

特定のセクションのマニュアルを表示したいときは、セクション番號を指定してください。例へば、セクション 3 にある "echo" を調べるなら、次のやうにします:

:Man 3 echo

マニュアルの中で "word(1)" のやうな形式で示されてゐる他のマニュアルにジャンプするには CTRL-] を押してください。":Man" コマンドが續けて使はれた場合は、同じウィンドウが使用されます。

カーソル下の單語のマニュアルを表示するには、次のコマンドを使ひます:

\K

(自分で <Leader> を再定義してゐる場合は、"‘\’" ではなく、それを使つてください) 例へば、次の行を編輯中に "strstr()" の戾り値を知りたくなつたら:

if ( strstr (input, "aap") == )

"strstr" の上にカーソルを移動し、"\K" と入力してください。ウィンドウが開いて strstr() のマニュアルが表示されます。

空白を取り除く

行末の空白は無用であり、浪費であり、見苦しいものであると考へる人々がゐます。すべての行末から空白を取り除くには、次のコマンドを使ひます:

:%s/\s\+$//

"%" を使つてすべての行を範圍指定してゐます。":substitute" コマンドに指定されてゐるパターンは "\s\+$" です。これは、空白文字 (\s) が一文字以上續き (\+)、行末($) で終はる文字列にマッチします。このやうなパターンの書き方は |usr_27.txt| で說明されてゐます。

"to" の部分は空 ("//") になつてゐます。空文字列で置き換へる、つまり、マッチした空白を削除するといふ意味になります。

もう 1 つの浪費パターンとして、tab の直前にスペースが使はれてゐる場合があります。たいていは、そのスペースを削除しても見た目の空白の量は變はりませんが、いつも大丈夫といふわけではありません。ですから、手作業で削除するのがベストです。次の檢索コマンドを使つてください:

/

何も見えないかもしれませんが、Tab 文字の直前にスペースがあります。つまりこれは "/<Space><Tab>" です。檢索したら、"x" コマンドを使つてスペースを削除し、見た目の變化がないことを確認してください。變化があつた場合は、tab 文字を插入して調整しませう。"n" を押して次の場所を檢索します。マッチするものがなくなるまで同じ操作を繰り返してください。

單語が使はれてゐる場所を檢索する

UNIX を使つてゐるなら、Vim と grep コマンドを組み合はせれば、指定した單語が含まれてゐるすべてのファイルを開くことができます。これは、プログラムを書いてゐるときに、特定の變數が使はれてゐるファイルを表示または編輯したい場合にとても便利です。

例へば、"frame_counter" といふ單語が含まれてゐるすべての C 言語ファイルを開くには、次のやうにします:

vim `grep -l frame_counter *.c`

このコマンドを詳しく見てみませう。"grep" コマンドは、指定されたファイルの中から單語を檢索します。"-l" 引數が指定されてゐるので、單語が含まれてゐるファイルの名前だけが表示されます。マッチした行は表示されません。檢索される單語は "frame_counter" です。單語の指定には正規表現が使へます。

Note:
grep で使へる正規表現は Vim の正規表現と完全に同じではありません。

コマンドはバッククォート (‘`’) で圍まれてゐます。これは、コマンドを實行し、その出力を、コマンドラインに入力されたものとして扱ふやうに UNIX シェルに指示してゐます。つまり、grep コマンドが實行され、出力されたファイルの一覽が Vim の引數に渡されます。Vim が起動した後は、":next" や ":first" などのコマンドでそれらのファイルを切り替へられます。

單語が使はれてゐる行を檢索する

上述のコマンドは單語が含まれてゐるファイルを見つけるだけなので、單語が使はれてゐる行は自分で檢索する必要がありました。

Vim には、指定された文字列を複數のファイルの中から檢索するための組み込みコマンドがあります。例へば、"error_string" といふ文字列をすべての C 言語ファイルの中から檢索するには、次のコマンドを使ひます:

:grep error_string *.c

指定されたファイル (*.c) の中から、"error_string" といふ文字列が檢索されます。コマンドを實行すると、文字列が含まれてゐる最初のファイルが開き、檢索にヒットした最初の行にカーソルが移動します。文字列が現れる次の場所 (同じファイルとは限りません) に移動するには、":cnext" コマンドを使ひます。1 つ前に戾るには ":cprev" コマンドを使ひます。":clist" コマンドを使ふと、檢索結果の一覽と現在位置が表示されます。

":grep" コマンドの實行には、外部プログラムの grep (Unix) または findstr (Windows) が使はれます。使はれるプログラムは ’grepprg’ オプションで變更できます。


Next: , Previous: , Up: 目次   [Index]