usr_10.txt For Vim バージョン 9.1. Last change: 2024 Nov 12
VIM USER MANUAL - by Bram Moolenaar
大規模な編集
四章では、小さな変更を加える方法について説明しました。この章では、同じ操作を再
実行する方法や、広範囲のテキストを変更する方法を説明します。ビジュアルモードで
は選択範囲にさまざまな処理を実行できます。外部プログラムを使えばとても複雑な処
理もできます。
10.1 操作の記録と再実行
10.2 置換
10.3 コマンドの範囲指定
10.4 global コマンド
10.5 矩形選択
10.6 ファイルの一部の保存と読み込み
10.7 テキストの整形
10.8 大文字/小文字の変換
10.9 外部プログラムを使う
次章: usr_11.txt クラッシュからの復帰
前章: usr_09.txt GUI を使う
目次: usr_toc.txt
==============================================================================
10.1 操作の記録と再実行
"." コマンドを使えば直前の変更を繰り返せますが、複数のコマンドを組み合わせた、
もっと複雑な操作を繰り返すにはどうすればいいでしょうか。それには記録コマンドを
使います。次の手順で記録できます:
1. "q{register}" コマンドを実行する。指定したレジスタ {register} へのキー入力
の記録が開始されます。レジスタ名は a から z のいずれかです。
2. コマンドを入力して編集する。
3. q を押して記録を終了する (レジスタの指定は必要ない)。
記録したマクロは "@{register}" コマンドで実行できます。
このコマンドの使い方を練習してみましょう。次のようなファイル名の一覧がありま
す:
stdio.h
fcntl.h
unistd.h
stdlib.h
これを次のように変更します:
#include "stdio.h"
#include "fcntl.h"
#include "unistd.h"
#include "stdlib.h"
まず、一行目の行頭に移動してください。そして次のコマンドを実行します。
qa レジスタ a へのマクロの記録を開始。
^ 行頭に移動。
i#include "<Esc> 行頭に #include " を挿入。
$ 行末に移動。
a"<Esc> 行末に引用符 (") を追加。
j 次の行に移動。
q マクロの記録を終了。
さて、一回分の作業はこれで終わりました。"@a" コマンドを使って変更を繰り返して
みてください。
"@a" コマンドには繰り返し回数を指定できます。三回繰り返すには、次のようにしま
す:
移動と実行
変更したい行がいろんな場所に分散している場合は、それぞれの場所に移動してから
"@a" コマンドを使います。一度でも再実行すると、次からは "@@" で同じマクロを再
実行できます。"@@" の方が少しだけ入力が簡単です。例えば、"@b" でレジスタ b を
実行すると、次に "@@" を実行したときはレジスタ b が使われます。
マクロの実行と "." にはいくつか違いがあります。まず第一に、"." は一つの変更し
か繰り返せません。上述の例のように、"@a" では複数の変更やカーソルの移動も繰り
返せます。第二に、"." は直前の変更しか繰り返せません。レジスタを実行する方法な
ら、他の変更を加えた後でも、"@a" を使って、記録されたコマンドを繰り返せます。
最後に、レジスタは 26 個あります。つまり、26 個のコマンド操作を記録しておける
のです。
レジスタを使う
記録に用いるレジスタはヤンクや削除で使っているのと同じものです。そのため、レジ
スタを操作して、記録されたコマンドと他のコマンドを合成することができます。
レジスタ n にいくつかのコマンドが記録されているとします。ところが、"@n" で実行
してみると、ミスがあることに気づきました。最初から記録をやり直すこともできます
が、また何か間違えてしまうかもしれません。代わりに、次のようなテクニックを使っ
てみましょう。
G ファイルの最後にジャンプ。
o<Esc> 空行を作成。
"np レジスタ n の内容をプット。記録されたコマンド
がテキストとして表示されます。
{edits} 間違っている部分を修正。普通にテキストを編集す
るのと同じです。
0 行頭に移動。
"ny$ 修正したコマンドをレジスタ n にヤンク
dd 不要になった最終行を削除
さて、"@n" で正しいコマンドが実行されるようになりました。(記録されたコマンドに
改行が含まれている場合は、上記の最後の二項目はその全内容が含まれるようにしてく
ださい)
レジスタに追記
これまで、レジスタ名には小文字を使ってきました。レジスタに追記するには大文字を
使います。
単語を変更するためのコマンドがレジスタ c に記録されているとします。これは正し
く動作するのですが、変更すべき次の単語を検索する処理を追加したくなりました。次
のようにすればできます:
レジスタ c に追記するために "qC" で記録を開始しています。レジスタ名を大文字で
書くと、同じレジスタに追記するという意味になるのです。
これは記録コマンドだけでなく、ヤンクや削除コマンドでも同じです。例えば、いくつ
かの行をレジスタ a に集めたいとします。最初の行を次のコマンドでヤンクしましょ
う:
次の行に移動し、このように入力します:
これを全ての行で実行します。レジスタ a にはヤンクした順にすべての行が保存され
ます。
==============================================================================
10.2 置換 find-replace
":substitute" コマンドを使うと、指定した範囲内の文字列を置換できます。コマンド
の書式は次のとおりです:
このコマンドは [range] で指定された行範囲の中の文字列 "from" を文字列 "to" に
置換します。例えば、次のコマンドを実行すると、すべての行の "Professor" が
"Teacher" に置換されます:
Note:
":substitute" の綴りを完全に入力するような人はまずいません。普通は短縮
形の ":s" が使われます。以降ではこの短縮形を使います。
コマンドの前の "%" はファイル全体を意味する範囲指定です。範囲指定がない場合は、
現在行のみ置換されます。範囲指定については次の節で述べます 10.3。
初期設定では、各行の最初に見つかったものだけが変更されます。例えば、上のコマン
ドを実行すると、次の行は:
Professor Smith criticized Professor Johnson today.
このように変更されます:
Teacher Smith criticized Professor Johnson today.
すべてを置換するには g (global) フラグを指定してください:
これを実行すると、先程の行は次のようになります。
Teacher Smith criticized Teacher Johnson today.
フラグは他にもあります。p (print=出力) フラグを指定すると、最後に変更された行
が表示されます。c (confirm=確認) フラグを指定すると、一つ一つ確認しながら置換
できます。次のようにして使います:
"Professor" が現れる最初の場所が検索され、置換される予定のテキストが表示されま
す。そして、次のようなプロンプトが表示されます:
ここでは次のいずれかの返答が必要です。
y Yes; 置換する。
n No; 置換せずにスキップ。
a All; 置換する。以降すべて確認なしで置換する。
q Quit; 置換を終了する。
l Last; 置換をしてから終了する。
CTRL-E 画面を一行上にスクロールする。
CTRL-Y 画面を一行下にスクロールする。
置換コマンドの "from" の部分は実際にはパターン (正規表現) です。これは検索コマ
ンドで使うのと同じものです。例えば、次のコマンドでは、行頭に現れる "the" のみ
が置換されます:
"from" や "to" にスラッシュ (/) を含めるには、バックスラッシュ (\) を前置する
必要がありますが、スラッシュの代わりに他の文字を使えばその必要はありません。例
えばプラス (+) など:
==============================================================================
10.3 コマンドの範囲指定
":substitute" などの : コマンドは、実行する範囲を指定できます。これを範囲指定
(range) と呼びます。
範囲指定の基本形式は {number},{number} です。例:
1 行目から 5 行目まで置換コマンドが実行されます。5 行目も範囲に入ります。範囲
指定はコマンドの前に指定してください。
特定の一行だけ指定するには、数字を一つだけ指定します:
一部のコマンドは範囲指定を省略するとファイル全体を処理します。そのようなコマン
ドで現在行だけを処理するには "." を使います。例えば、":write" コマンドの範囲指
定を省略するとファイル全体が保存されますが、現在行だけを保存するには、次のよう
にします:
一行目の行番号は 1 です。最終行は "$" で指定できます。例えば、現在行から最終行
までの範囲で置換をするには、次のようにします:
先程使った "%" は "1,$"、つまり一行目から最終行までと同じことです。
パターンを使った範囲指定
例えば、本のどこかの章を編集していて、その章で使われている "grey" を全て
"gray" に置換したいとします。ただし、その章だけを置換、つまり次章は変更したく
ありません。章は行頭が "Chapter" で始まる行で区切られています。次のコマンドで
それができます:
パターン検索が二回使われています。最初の "?^Chapter?" では現在行から上に向かっ
て検索しています。この ?pattern? という範囲の書き方は後方検索をするために使い
ます。同様に、"/^Chapter/" で前方検索を行い、次章の先頭を検索しています。
上の例では、説明をわかりやすくするために、置換コマンドの区切りに "=" を使って
います。スラッシュでも他の文字でも動作に違いはありません。
加算と減算
実は上のコマンドには少しだけ間違いがあります。次章のタイトルに "grey" が含まれ
ていると、それも置換されてしまいます。それが期待どおりの動作ならいいのですが、
そうでなければ? その場合はオフセットを指定すればよいのです。
パターンを検索し、その一行上の行を使うには、次のようにします:
数字は 1 でなくても構いません。ヒットした行の 2 行下を指定するなら、次のように
します:
オフセットは他の範囲指定にも使えます。例えば:
これは、現在行の 3 行下から、最終行の 5 行上までの範囲を指定しています。
マークを使う
行番号を直接指定する代わりに、マークを使うこともできます。
マークの使い方は三章で説明しました。例えば、範囲指定したい領域の先頭を "mt" で
マークし、領域の末尾を "mb" でマークします。すると、マークを使って次のように範
囲指定をすることができます (マークのある行は範囲に含まれます):
ビジュアルモードと範囲指定
ビジュアルモードでテキストを選択し、":" を押してコマンドラインモードに入ると、
次のような表示になります:
この状態でコマンドを入力すると、そのコマンドはビジュアル選択した範囲に対して適
用されます。
Note:
行の一部だけビジュアルモードで選択した場合や、CTRL-V で矩形選択した場
合でも、コマンドは行全体に適用されます。これは将来、変更されるかも知れ
ません。
実は、'< と '> はマークです。ビジュアル選択の始点と終点を示しています。このマー
クは、次にビジュアル選択するまで同じ場所を指しています。そのため、"'<" コマン
ドでその場所にジャンプすることもできます。マークと他の範囲指定方法を組み合わせ
ることもできます:
これは、選択範囲の終点からファイルの末尾までを範囲指定しています。
行数指定
変更したい行数が分かっているなら、その数を入力してから ":" を押してください。
例えば、"5:" と入力すると、次のような表示になります:
続けて、使いたいコマンドを入力してください。これは、"." (現在行) から ".+4" (4
行下) が範囲指定されています。つまり範囲は 5 行ということです。
==============================================================================
10.4 global コマンド
":global" コマンドは Vim の中でも最も強力な機能の一つです。パターンにヒットす
る行を検索し、その行で、任意のコマンドを実行できます。コマンドの書式は次のとお
りです:
":substitute" コマンドに似ていますが、文字列が置換されるのではなく、{command}
コマンドが実行されます。
Note:
":global" で実行できるのは ":" で始まるコマンドだけです。ノーマルモー
ドコマンドはそのままでは使えません。:normalコマンドを使ってください。
例えば、C++ スタイルのコメント内の "foobar" を "barfoo" に置換したいとします。
コメントは "//" で開始されています。次のコマンドを使いましょう:
最初の ":g" は ":global" の短縮形です。":substitute" を ":s" と縮めるのと同じ
です。次に "+" 記号で囲まれたパターンがあります。今回はスラッシュを含んだパター
ンを検索するので、セパレータに "+" を使っています。その後に、"foobar" を
"barfoo" に置換するコマンドが続きます。
範囲指定を省略した場合、global コマンドはファイル全体に適用されます。そのため、
上の例では範囲指定をしていません。この点は、":substitute" が、範囲指定を省略す
ると現在行だけ処理するのと異なっています。
このコマンドは完璧ではありません。"//" が行の途中にあった場合もヒットしてしま
うので、行頭から "//" までの文字も置換されてしまいます。
":substitute" と同じく、どんなパターンでも使えます。もっと複雑なパターンを覚え
たら使ってみてください。
==============================================================================
10.5 矩形選択
CTRL-V を使うと、テキストの矩形部分を選択することができます。ここでは、矩形選
択でのみ使える特殊なコマンドを説明します。
矩形選択では、"$" コマンドに特殊な意味があります。"$" で移動した直後は、選択範
囲のすべての行で、選択範囲が行末まで拡張されます。現在行より長い行も行末まで選
択されます。この選択効果は、左右の移動をすると失われてしまいます。つまり、"j"
なら効果は残りますが、"h" では元に戻ってしまいます。
テキストの挿入
"I{string}<Esc>" コマンドを使うと、各行の、矩形選択した左側に {string} を挿入
できます。例えば、CTRL-V を押して矩形選択を開始し、カーソルを動かして選択範囲
を設定します。次に I を押して挿入モードに入り、テキストを挿入します。このとき、
挿入したテキストは最初の行にだけ表示されます。
<Esc> を押して挿入モードを抜けると、テキストが魔法のように選択範囲の残りの行に
挿入されます。例:
include one
include two
include three
include four
カーソルを "one" の "o" に移動し CTRL-V を押します。"3j" で、"four" まで移動し
ます。これで 4 行が矩形選択されました。そして、次のコマンドを入力します:
結果は次のようになります:
include main.one
include main.two
include main.three
include main.four
選択範囲の途中に短い行があって、その行の文字が選択範囲に入ってなかった場合は、
その行には何も挿入されません。例えば、以下のテキストで、一行目と三行目の
"long" を矩形選択します。二行目は短いので何も選択されていません:
This is a long line
short
Any other long line
^^^^ 選択範囲
そして、"Ivery <Esc>" を入力すると、次のようになります:
This is a very long line
short
Any other very long line
短い行には何も挿入されません。
改行を含むテキストを挿入した場合、"I" は通常の挿入コマンドと同じ動作をします。
つまり、最初の行にだけテキストが挿入されます。
"A" コマンドも同様の動作をします。ただし、テキストは右側に挿入されます。そし
て、短い行にもテキストが挿入されます。"I" と使い分ければ、短い行にテキストを挿
入するかどうかを選択することができます。
"A" には特別な場合が一つあります。矩形選択時に "$" を使って各行の行末まで選択
範囲を拡張した場合、"A" を使うと各行の行末にテキストが追加されます。
上と同じ例を使って、今度は "$A XXX<Esc>" と入力すると、結果は次のようになりま
す:
This is a long line XXX
short XXX
Any other long line XXX
"$" を使わなければこの効果は出せません。Vim は "$" が使われたかどうかを記憶し
ています。カーソルを一番長い行の行末に移動し、見た目の選択範囲を同じにしても、
同じ結果にはなりません。
テキストの変更
矩形選択で "c" コマンドを使うと、選択範囲が削除され、挿入モードに入ります。入
力された文字列は選択されていた各行に挿入されます。
上と同じ例を使って、"long" を選択しているときに今度は "c_LONG_<Esc>" と入力す
ると、結果は次のようになります:
This is a _LONG_ line
short
Any other _LONG_ line
"I" コマンドの場合と同じく、短い行は無視されます。また、新しい文字列には改行は
入力できません。
"C" コマンドの場合は、ブロックの左端から行末までが削除されます。そして、挿入
モードに入り、文字列を入力できるようになります。その文字列は各行の行末に追加さ
れます。
また同じ例ですが、今度は "Cnew text<Esc>" と入力すると、結果は次のようになりま
す。
This is a new text
short
Any other new text
注意すべきは、"long" という単語だけが選択されていても、これを実行すると、行末
まで全部消えてしまう点です。つまり、選択範囲の左端の位置だけが意味を持ちます。
繰り返しですが、文字が選択されていない短い行はここでも無視されます。
その他に、矩形選択内の文字列を変更するコマンドには次のようなものがあります。
~ 大文字/小文字切換え (a -> A and A -> a)
U 大文字化する (a -> A and A -> A)
u 小文字化する (a -> a and A -> a)
1 つの文字で埋める
選択範囲全体を一つの文字で埋めるには "r" コマンドを使います。またまた、上で用
いた例ですが、今度は "long" を選択した上で "rx" と入力します:
This is a xxxx line
short
Any other xxxx line
Note:
行末を越えて矩形選択したい場合は、25 章の 'virtualedit' の説明を参照し
てください。
シフト
">" コマンドを使うと、選択されたテキストを右側にシフトできます。間は空白で埋め
られます。シフトの開始位置は矩形選択の左端です。
また同じ例を使って、今度は ">" を実行すると次のようになります:
This is a long line
short
Any other long line
シフトされる桁数は 'shiftwidth' オプションで設定します。これを 4 に変更するに
は次のようにします:
"<" コマンドを使うと、選択範囲の左側にある空白を一つのシフト分だけ削除できま
す。このコマンドは選択範囲の左側にある空白の量によって制限されます。つまり、空
白がシフト量より少ない場合は、可能な範囲だけ空白が削除されます。
行の結合
"J" コマンドを使うと、選択範囲の行を一行に連結できます。つまり改行が削除されま
す。正確には、改行、行頭の空白、行末の空白、が一つの空白で置換されます
('joinspaces' オプションで動作を変更できます)。
さて、また同じ例を使って、今度は "J" を実行します:
This is a long line short Any other long line
"J" コマンドは矩形選択以外でも使えます。"v" や "V" で選択した場合も全く同じ動
作をします。
空白を変更したくない場合は、"gJ" コマンドを使ってください。
==============================================================================
10.6 ファイルの一部の保存と読み込み
メールを書いているとき、他のファイルを取り込みたいことがあるかもしれません。そ
れには ":read {filename}" コマンドを使います。指定したファイルの内容が現在行の
下にプットされます。
次の文章でやってみましょう。
Hi John,
Here is the diff that fixes the bug:
Bye, Pierre.
カーソルを二行目に移動し、次のコマンドを入力します:
"patch" という名前のファイルが挿入され、次のようになります:
Hi John,
Here is the diff that fixes the bug:
2c2
< for (i = 0; i <= length; ++i)
---
> for (i = 0; i < length; ++i)
Bye, Pierre.
":read" コマンドに範囲指定すると、指定されたファイルが範囲指定された行の下に
プットされます。例えば、":$r patch" なら、"patch" の内容がファイルの末尾に追加
されます。
ファイルの先頭に読み込むにはどうすればいいでしょうか。それには、行番号 0 を指
定します。そのような行は実際にはないので、他のコマンドに指定するとエラーになる
かもしれませんが、このコマンドでは指定できます:
"patch" の内容がファイルの先頭にプットされます。
ファイルの一部だけ保存
ファイルの一部だけ保存するには、":write" コマンドを使います。範囲指定を省略す
るとファイル全体が保存されますが、範囲指定すると、指定した範囲の行だけが保存さ
れます:
このコマンドで、現在行から最終行までが "tempo" に保存されます。ファイルが既に
存在している場合はエラーメッセージが表示されるので、間違ってファイルを上書きす
る心配はありません。ファイルを上書きしたい場合は、! を付けてください:
注意: ! は ":write" コマンドの直後に指定してください。間に空白を入れると、フィ
ルタコマンドになってしまいます。フィルタコマンドについては後で説明します。
ファイルに追記する
この章の最初の節で、複数の行をレジスタに集める方法を説明しました。同じように、
複数の行をファイルに集めることができます。まず、次のコマンドで最初の行を保存し
てください:
次に、二行目として保存したい行に移動し、次のように入力します:
新規ファイルとして保存するのではなく、">>" を使って、ファイルの末尾に追記する
ことを指示しています。あとは必要なだけこの操作を繰り返してください。
==============================================================================
10.7 テキストの整形
文章を入力しているとき、行が画面内に収まるように自動的に改行してくれたら便利で
すよね。そうするには、'textwidth' オプションを設定します:
vimrc ファイルの見本 (vimrc_example.vim) で、テキストファイルが開かれたとき
にこのオプションが設定されるようにしていたのを覚えているでしょうか。したがっ
て、vimrc ファイルの見本をそのまま使っているなら、オプションは既に設定されてい
ます。現在の 'textwidth' の設定を確認するには、次のようにします:
これで、行が 72 文字より長くなった行が改行されるようになりました。ただし、行の
途中からテキストを挿入したときや、単語削除をしたときは、行が 72 文字よりも長く
なったり短くなったりします。既存の文章が自動的に再整形されたりはしません。
現在の段落を整形するには、次のコマンドを使います:
これは "gq" というオペレータで始まるコマンドです。次に "ap" というテキストオブ
ジェクトが指定されています。これは "a paragraph" (一つの段落) という意味です。
段落は、空行で区切られたテキストです。
Note:
空行 (改行文字だけの行) と空白行 (空白文字だけの行) は違います。段落の
区切りは「空行」だけです。見た目では気づきにくいので注意!
"ap" 以外のテキストオブジェクトや、移動コマンドも指定できます。段落が正しく分
割されているなら、次のコマンドでファイル全体を整形できます:
これは、"gg" で一行目に移動し、"gq" で整形オペレータを指定、"G" でファイル末尾
までジャンプしています。
段落の区切りが明確でない場合は、手動で行を選択して整形してください。整形したい
範囲の最初の行に移動し、"gqj" コマンドを使います。現在行と次の行が整形されま
す。現在行が短い場合は、次の行の単語が現在行に移動します。現在行が長い場合は、
現在行の単語が次の行に移動します。カーソルは次の行に移動しているので、"." でコ
マンドを再実行できます。あとは必要なだけ繰り返してください。
==============================================================================
10.8 大文字/小文字の変換
"section header" という小文字のテキストがあります。これを、"section" だけ大文
字にするには、"gU" オペレータを使います。カーソルを先頭に移動して、コマンドを
実行してください:
"gu" オペレータで小文字に変換できます:
"g~" を使うと、大文字と小文字を切り替えることができます。今説明したのは全てオ
ペレータなので、移動コマンドやテキストオブジェクトやビジュアルモードと組み合わ
せることができます。
オペレータを行に適用するには、オペレータを二回繰り返してください。例えば、"d"
は削除オペレータなので、"dd" で一行削除になります。同じように、"gugu" で行全体
が小文字になります。もっと短く、"guu" でも構いません。"gUgU" は "gUU"、"g~g~"
は "g~~" と短縮できます。例:
==============================================================================
10.9 外部プログラムを使う
Vim には強力なコマンドがたくさんあるので何でもできますが、外部プログラムを使っ
た方がもっときれいで高速に処理できる場合もあります。
"!{motion}{program}" コマンドを使うと、ファイルの一部を、外部プログラムでフィ
ルタすることができます。つまり、{program} で指定したプログラムが実行され、
{motion} で指定した範囲のテキストがプログラムに入力され、指定された範囲のテキ
ストがプログラムの出力で置き換えられます。
UNIX のフィルタに馴染のない方にはわかりにくいと思うので、例を交えて説明します。
sort コマンドはファイルの中身をソート (並べ替え) するコマンドです。次のコマン
ドを実行すると、ソートされていない input.txt の中身が整列され、output.txt に保
存されます。(この例は UNIX でも Microsoft Windows でも動作します)
さて、同じことを Vim でやってみましょう。1 行目から 5 行目までをソートしてみま
す。カーソルを一行目に移動して、次のコマンドを実行します:
"!" はフィルタを実行するためのコマンドです。次に、移動コマンドを実行し、フィル
タに渡す範囲を指定しています。"5G" は 5 行目に移動するコマンドなので、1 行目
(現在行) から 5 行目までがフィルタの範囲として指定されます。
カーソルが画面の一番下に移動し、! プロンプトが表示されるので、フィルタプログラ
ムの名前を入力してください。この場合なら "sort" ですね。したがって、コマンドは
全部で次のようになります。
コマンドを実行すると、最初の五行が sort プログラムで処理され、元のテキストが、
プログラムの出力で置き換えられます。
line 55 line 11
line 33 line 22
line 11 --> line 33
line 22 line 44
line 44 line 55
last line last line
"!!" コマンドを使うと、現在行をフィルタできます。Unix では "date" コマンドで現
在の日時を出力できるので、"!!date<Enter>" で現在行を "date" の出力で置き換える
ことができます。これはファイルに日付を挿入するのに便利です。
Note: "!cmd" (例: ファイル範囲なしで使用する) と "{range}!cmd" には違いがあり
ます。前者は単に外部コマンドを実行し、Vim は出力を表示しますが、後者はフィル
ターを通して {range} 行をフィルターし、その範囲をフィルターコマンドの結果で置
き換えます。詳細については、:! および :range! を参照してください。
うまく動作しない場合
シェルを起動し、テキストを入力し、出力を取り込むためには、シェルが正しく実行で
きるように設定されている必要があります。フィルタ処理に問題がある場合は、以下の
オプションを確認してください。
'shell' 外部プログラムを実行するために使われるプログラムの指定
'shellcmdflag' シェルにコマンドを渡すための引数指定
'shellquote' コマンドを囲むためのクォート文字
'shellxquote' コマンドとリダイレクトを囲むためのクォート文字
'shelltype' シェルの種類 (Amiga専用)
'shellslash' ファイル名のバックスラッシュをスラッシュにする
(MS-Windows 系専用)
'shellredir' コマンドの出力をファイルに保存するために指定する文字列
Unix では、設定する必要はほとんどありません。なぜなら、おそらく sh 系か csh 系
のシェルが使われているからです。Vim は 'shell' に "csh" という文字列が含まれて
いるかどうかでシェルの種類を判断し、関連したオプションを自動的に設定します。
しかし、MS-Windows ではいろんなシェルがあるので、フィルタを動作させるためには、
オプションを設定する必要があるかもしれません。詳しくはオプションのヘルプを参照
してください。
コマンドの出力を読み込む
カレントディレクトリの内容を読み込むには、次のようにします。
Unix系:
"ls" や "dir" コマンドの出力が取り込まれ、カーソルの下に挿入されます。これは
ファイルの読み込みに似ていますが、"!" を使ってコマンドを指定している点が違いま
す。
コマンドに引数を指定することもできます。出力をプットする場所を指定することもで
きます:
これはファイルの先頭に現在の日付と時間を UTC 形式で挿入します ("-u" 引数が使え
る date コマンドが必要ですよ。当たり前ですが...)。Note: "!!date" が現在行を置
き換えるのに対して、":read !date" は行を挿入するという点が違います。
コマンドにテキストを入力する
Unix の "wc" コマンドは単語を数えることができます。編集中のファイル内の単語を
数えるには、次のようにします:
これは上述の write コマンドと似ていますが、"!" を使って外部プログラムを指定し
ている点が違います。テキストがコマンドの標準入力に渡され、次のような結果が表示
されます:
4 47 249
"wc" コマンドは冗長なメッセージを出力しません。この出力は、行数が 4、単語数が
47、文字数が 249 であることを示しています。
次のような間違いに気をつけてください:
これはカレントディレクトリの "wc" というファイルに強制上書きするコマンドです。
空白は重要ですよ!
画面の再描画
外部プログラムがエラーを起こした場合、画面がめちゃくちゃになってしまうことがあ
ります。Vim は必要だと思われる最小限の領域だけを再描画しますが、他のプログラム
の出力内容を完全に把握することはできません。次のコマンドで画面を再描画できま
す:
==============================================================================
次章: usr_11.txt クラッシュからの復帰
Copyright: see manual-copyright vim:tw=78:ts=8:noet:ft=help:norl:
VIM USER MANUAL - by Bram Moolenaar
大規模な編集
四章では、小さな変更を加える方法について説明しました。この章では、同じ操作を再
実行する方法や、広範囲のテキストを変更する方法を説明します。ビジュアルモードで
は選択範囲にさまざまな処理を実行できます。外部プログラムを使えばとても複雑な処
理もできます。
10.1 操作の記録と再実行
10.2 置換
10.3 コマンドの範囲指定
10.4 global コマンド
10.5 矩形選択
10.6 ファイルの一部の保存と読み込み
10.7 テキストの整形
10.8 大文字/小文字の変換
10.9 外部プログラムを使う
次章: usr_11.txt クラッシュからの復帰
前章: usr_09.txt GUI を使う
目次: usr_toc.txt
==============================================================================
10.1 操作の記録と再実行
"." コマンドを使えば直前の変更を繰り返せますが、複数のコマンドを組み合わせた、
もっと複雑な操作を繰り返すにはどうすればいいでしょうか。それには記録コマンドを
使います。次の手順で記録できます:
1. "q{register}" コマンドを実行する。指定したレジスタ {register} へのキー入力
の記録が開始されます。レジスタ名は a から z のいずれかです。
2. コマンドを入力して編集する。
3. q を押して記録を終了する (レジスタの指定は必要ない)。
記録したマクロは "@{register}" コマンドで実行できます。
このコマンドの使い方を練習してみましょう。次のようなファイル名の一覧がありま
す:
stdio.h
fcntl.h
unistd.h
stdlib.h
これを次のように変更します:
#include "stdio.h"
#include "fcntl.h"
#include "unistd.h"
#include "stdlib.h"
まず、一行目の行頭に移動してください。そして次のコマンドを実行します。
qa レジスタ a へのマクロの記録を開始。
^ 行頭に移動。
i#include "<Esc> 行頭に #include " を挿入。
$ 行末に移動。
a"<Esc> 行末に引用符 (") を追加。
j 次の行に移動。
q マクロの記録を終了。
さて、一回分の作業はこれで終わりました。"@a" コマンドを使って変更を繰り返して
みてください。
"@a" コマンドには繰り返し回数を指定できます。三回繰り返すには、次のようにしま
す:
3@a
移動と実行
変更したい行がいろんな場所に分散している場合は、それぞれの場所に移動してから
"@a" コマンドを使います。一度でも再実行すると、次からは "@@" で同じマクロを再
実行できます。"@@" の方が少しだけ入力が簡単です。例えば、"@b" でレジスタ b を
実行すると、次に "@@" を実行したときはレジスタ b が使われます。
マクロの実行と "." にはいくつか違いがあります。まず第一に、"." は一つの変更し
か繰り返せません。上述の例のように、"@a" では複数の変更やカーソルの移動も繰り
返せます。第二に、"." は直前の変更しか繰り返せません。レジスタを実行する方法な
ら、他の変更を加えた後でも、"@a" を使って、記録されたコマンドを繰り返せます。
最後に、レジスタは 26 個あります。つまり、26 個のコマンド操作を記録しておける
のです。
レジスタを使う
記録に用いるレジスタはヤンクや削除で使っているのと同じものです。そのため、レジ
スタを操作して、記録されたコマンドと他のコマンドを合成することができます。
レジスタ n にいくつかのコマンドが記録されているとします。ところが、"@n" で実行
してみると、ミスがあることに気づきました。最初から記録をやり直すこともできます
が、また何か間違えてしまうかもしれません。代わりに、次のようなテクニックを使っ
てみましょう。
G ファイルの最後にジャンプ。
o<Esc> 空行を作成。
"np レジスタ n の内容をプット。記録されたコマンド
がテキストとして表示されます。
{edits} 間違っている部分を修正。普通にテキストを編集す
るのと同じです。
0 行頭に移動。
"ny$ 修正したコマンドをレジスタ n にヤンク
dd 不要になった最終行を削除
さて、"@n" で正しいコマンドが実行されるようになりました。(記録されたコマンドに
改行が含まれている場合は、上記の最後の二項目はその全内容が含まれるようにしてく
ださい)
レジスタに追記
これまで、レジスタ名には小文字を使ってきました。レジスタに追記するには大文字を
使います。
単語を変更するためのコマンドがレジスタ c に記録されているとします。これは正し
く動作するのですが、変更すべき次の単語を検索する処理を追加したくなりました。次
のようにすればできます:
qC/word<Enter>q
レジスタ c に追記するために "qC" で記録を開始しています。レジスタ名を大文字で
書くと、同じレジスタに追記するという意味になるのです。
これは記録コマンドだけでなく、ヤンクや削除コマンドでも同じです。例えば、いくつ
かの行をレジスタ a に集めたいとします。最初の行を次のコマンドでヤンクしましょ
う:
"aY
次の行に移動し、このように入力します:
"AY
これを全ての行で実行します。レジスタ a にはヤンクした順にすべての行が保存され
ます。
==============================================================================
10.2 置換 find-replace
":substitute" コマンドを使うと、指定した範囲内の文字列を置換できます。コマンド
の書式は次のとおりです:
:[range]substitute/from/to/[flags]
このコマンドは [range] で指定された行範囲の中の文字列 "from" を文字列 "to" に
置換します。例えば、次のコマンドを実行すると、すべての行の "Professor" が
"Teacher" に置換されます:
:%substitute/Professor/Teacher/
Note:
":substitute" の綴りを完全に入力するような人はまずいません。普通は短縮
形の ":s" が使われます。以降ではこの短縮形を使います。
コマンドの前の "%" はファイル全体を意味する範囲指定です。範囲指定がない場合は、
現在行のみ置換されます。範囲指定については次の節で述べます 10.3。
初期設定では、各行の最初に見つかったものだけが変更されます。例えば、上のコマン
ドを実行すると、次の行は:
Professor Smith criticized Professor Johnson today.
このように変更されます:
Teacher Smith criticized Professor Johnson today.
すべてを置換するには g (global) フラグを指定してください:
:%s/Professor/Teacher/g
これを実行すると、先程の行は次のようになります。
Teacher Smith criticized Teacher Johnson today.
フラグは他にもあります。p (print=出力) フラグを指定すると、最後に変更された行
が表示されます。c (confirm=確認) フラグを指定すると、一つ一つ確認しながら置換
できます。次のようにして使います:
:%s/Professor/Teacher/c
"Professor" が現れる最初の場所が検索され、置換される予定のテキストが表示されま
す。そして、次のようなプロンプトが表示されます:
Teacher に置換しますか? (y/n/a/q/l/^E/^Y)
ここでは次のいずれかの返答が必要です。
y Yes; 置換する。
n No; 置換せずにスキップ。
a All; 置換する。以降すべて確認なしで置換する。
q Quit; 置換を終了する。
l Last; 置換をしてから終了する。
CTRL-E 画面を一行上にスクロールする。
CTRL-Y 画面を一行下にスクロールする。
置換コマンドの "from" の部分は実際にはパターン (正規表現) です。これは検索コマ
ンドで使うのと同じものです。例えば、次のコマンドでは、行頭に現れる "the" のみ
が置換されます:
:s/^the/these/
"from" や "to" にスラッシュ (/) を含めるには、バックスラッシュ (\) を前置する
必要がありますが、スラッシュの代わりに他の文字を使えばその必要はありません。例
えばプラス (+) など:
:s+one/two+one or two+
==============================================================================
10.3 コマンドの範囲指定
":substitute" などの : コマンドは、実行する範囲を指定できます。これを範囲指定
(range) と呼びます。
範囲指定の基本形式は {number},{number} です。例:
:1,5s/this/that/g
1 行目から 5 行目まで置換コマンドが実行されます。5 行目も範囲に入ります。範囲
指定はコマンドの前に指定してください。
特定の一行だけ指定するには、数字を一つだけ指定します:
:54s/President/Fool/
一部のコマンドは範囲指定を省略するとファイル全体を処理します。そのようなコマン
ドで現在行だけを処理するには "." を使います。例えば、":write" コマンドの範囲指
定を省略するとファイル全体が保存されますが、現在行だけを保存するには、次のよう
にします:
:.write otherfile
一行目の行番号は 1 です。最終行は "$" で指定できます。例えば、現在行から最終行
までの範囲で置換をするには、次のようにします:
:.,$s/yes/no/
先程使った "%" は "1,$"、つまり一行目から最終行までと同じことです。
パターンを使った範囲指定
例えば、本のどこかの章を編集していて、その章で使われている "grey" を全て
"gray" に置換したいとします。ただし、その章だけを置換、つまり次章は変更したく
ありません。章は行頭が "Chapter" で始まる行で区切られています。次のコマンドで
それができます:
:?^Chapter?,/^Chapter/s=grey=gray=g
パターン検索が二回使われています。最初の "?^Chapter?" では現在行から上に向かっ
て検索しています。この ?pattern? という範囲の書き方は後方検索をするために使い
ます。同様に、"/^Chapter/" で前方検索を行い、次章の先頭を検索しています。
上の例では、説明をわかりやすくするために、置換コマンドの区切りに "=" を使って
います。スラッシュでも他の文字でも動作に違いはありません。
加算と減算
実は上のコマンドには少しだけ間違いがあります。次章のタイトルに "grey" が含まれ
ていると、それも置換されてしまいます。それが期待どおりの動作ならいいのですが、
そうでなければ? その場合はオフセットを指定すればよいのです。
パターンを検索し、その一行上の行を使うには、次のようにします:
/Chapter/-1
数字は 1 でなくても構いません。ヒットした行の 2 行下を指定するなら、次のように
します:
/Chapter/+2
オフセットは他の範囲指定にも使えます。例えば:
:.+3,$-5
これは、現在行の 3 行下から、最終行の 5 行上までの範囲を指定しています。
マークを使う
行番号を直接指定する代わりに、マークを使うこともできます。
マークの使い方は三章で説明しました。例えば、範囲指定したい領域の先頭を "mt" で
マークし、領域の末尾を "mb" でマークします。すると、マークを使って次のように範
囲指定をすることができます (マークのある行は範囲に含まれます):
:'t,'b
ビジュアルモードと範囲指定
ビジュアルモードでテキストを選択し、":" を押してコマンドラインモードに入ると、
次のような表示になります:
:'<,'>
この状態でコマンドを入力すると、そのコマンドはビジュアル選択した範囲に対して適
用されます。
Note:
行の一部だけビジュアルモードで選択した場合や、CTRL-V で矩形選択した場
合でも、コマンドは行全体に適用されます。これは将来、変更されるかも知れ
ません。
実は、'< と '> はマークです。ビジュアル選択の始点と終点を示しています。このマー
クは、次にビジュアル選択するまで同じ場所を指しています。そのため、"'<" コマン
ドでその場所にジャンプすることもできます。マークと他の範囲指定方法を組み合わせ
ることもできます:
:'>,$
これは、選択範囲の終点からファイルの末尾までを範囲指定しています。
行数指定
変更したい行数が分かっているなら、その数を入力してから ":" を押してください。
例えば、"5:" と入力すると、次のような表示になります:
:.,.+4
続けて、使いたいコマンドを入力してください。これは、"." (現在行) から ".+4" (4
行下) が範囲指定されています。つまり範囲は 5 行ということです。
==============================================================================
10.4 global コマンド
":global" コマンドは Vim の中でも最も強力な機能の一つです。パターンにヒットす
る行を検索し、その行で、任意のコマンドを実行できます。コマンドの書式は次のとお
りです:
:[range]global/{pattern}/{command}
":substitute" コマンドに似ていますが、文字列が置換されるのではなく、{command}
コマンドが実行されます。
Note:
":global" で実行できるのは ":" で始まるコマンドだけです。ノーマルモー
ドコマンドはそのままでは使えません。:normalコマンドを使ってください。
例えば、C++ スタイルのコメント内の "foobar" を "barfoo" に置換したいとします。
コメントは "//" で開始されています。次のコマンドを使いましょう:
:g+//+s/foobar/barfoo/g
最初の ":g" は ":global" の短縮形です。":substitute" を ":s" と縮めるのと同じ
です。次に "+" 記号で囲まれたパターンがあります。今回はスラッシュを含んだパター
ンを検索するので、セパレータに "+" を使っています。その後に、"foobar" を
"barfoo" に置換するコマンドが続きます。
範囲指定を省略した場合、global コマンドはファイル全体に適用されます。そのため、
上の例では範囲指定をしていません。この点は、":substitute" が、範囲指定を省略す
ると現在行だけ処理するのと異なっています。
このコマンドは完璧ではありません。"//" が行の途中にあった場合もヒットしてしま
うので、行頭から "//" までの文字も置換されてしまいます。
":substitute" と同じく、どんなパターンでも使えます。もっと複雑なパターンを覚え
たら使ってみてください。
==============================================================================
10.5 矩形選択
CTRL-V を使うと、テキストの矩形部分を選択することができます。ここでは、矩形選
択でのみ使える特殊なコマンドを説明します。
矩形選択では、"$" コマンドに特殊な意味があります。"$" で移動した直後は、選択範
囲のすべての行で、選択範囲が行末まで拡張されます。現在行より長い行も行末まで選
択されます。この選択効果は、左右の移動をすると失われてしまいます。つまり、"j"
なら効果は残りますが、"h" では元に戻ってしまいます。
テキストの挿入
"I{string}<Esc>" コマンドを使うと、各行の、矩形選択した左側に {string} を挿入
できます。例えば、CTRL-V を押して矩形選択を開始し、カーソルを動かして選択範囲
を設定します。次に I を押して挿入モードに入り、テキストを挿入します。このとき、
挿入したテキストは最初の行にだけ表示されます。
<Esc> を押して挿入モードを抜けると、テキストが魔法のように選択範囲の残りの行に
挿入されます。例:
include one
include two
include three
include four
カーソルを "one" の "o" に移動し CTRL-V を押します。"3j" で、"four" まで移動し
ます。これで 4 行が矩形選択されました。そして、次のコマンドを入力します:
Imain.<Esc>
結果は次のようになります:
include main.one
include main.two
include main.three
include main.four
選択範囲の途中に短い行があって、その行の文字が選択範囲に入ってなかった場合は、
その行には何も挿入されません。例えば、以下のテキストで、一行目と三行目の
"long" を矩形選択します。二行目は短いので何も選択されていません:
This is a long line
short
Any other long line
^^^^ 選択範囲
そして、"Ivery <Esc>" を入力すると、次のようになります:
This is a very long line
short
Any other very long line
短い行には何も挿入されません。
改行を含むテキストを挿入した場合、"I" は通常の挿入コマンドと同じ動作をします。
つまり、最初の行にだけテキストが挿入されます。
"A" コマンドも同様の動作をします。ただし、テキストは右側に挿入されます。そし
て、短い行にもテキストが挿入されます。"I" と使い分ければ、短い行にテキストを挿
入するかどうかを選択することができます。
"A" には特別な場合が一つあります。矩形選択時に "$" を使って各行の行末まで選択
範囲を拡張した場合、"A" を使うと各行の行末にテキストが追加されます。
上と同じ例を使って、今度は "$A XXX<Esc>" と入力すると、結果は次のようになりま
す:
This is a long line XXX
short XXX
Any other long line XXX
"$" を使わなければこの効果は出せません。Vim は "$" が使われたかどうかを記憶し
ています。カーソルを一番長い行の行末に移動し、見た目の選択範囲を同じにしても、
同じ結果にはなりません。
テキストの変更
矩形選択で "c" コマンドを使うと、選択範囲が削除され、挿入モードに入ります。入
力された文字列は選択されていた各行に挿入されます。
上と同じ例を使って、"long" を選択しているときに今度は "c_LONG_<Esc>" と入力す
ると、結果は次のようになります:
This is a _LONG_ line
short
Any other _LONG_ line
"I" コマンドの場合と同じく、短い行は無視されます。また、新しい文字列には改行は
入力できません。
"C" コマンドの場合は、ブロックの左端から行末までが削除されます。そして、挿入
モードに入り、文字列を入力できるようになります。その文字列は各行の行末に追加さ
れます。
また同じ例ですが、今度は "Cnew text<Esc>" と入力すると、結果は次のようになりま
す。
This is a new text
short
Any other new text
注意すべきは、"long" という単語だけが選択されていても、これを実行すると、行末
まで全部消えてしまう点です。つまり、選択範囲の左端の位置だけが意味を持ちます。
繰り返しですが、文字が選択されていない短い行はここでも無視されます。
その他に、矩形選択内の文字列を変更するコマンドには次のようなものがあります。
~ 大文字/小文字切換え (a -> A and A -> a)
U 大文字化する (a -> A and A -> A)
u 小文字化する (a -> a and A -> a)
1 つの文字で埋める
選択範囲全体を一つの文字で埋めるには "r" コマンドを使います。またまた、上で用
いた例ですが、今度は "long" を選択した上で "rx" と入力します:
This is a xxxx line
short
Any other xxxx line
Note:
行末を越えて矩形選択したい場合は、25 章の 'virtualedit' の説明を参照し
てください。
シフト
">" コマンドを使うと、選択されたテキストを右側にシフトできます。間は空白で埋め
られます。シフトの開始位置は矩形選択の左端です。
また同じ例を使って、今度は ">" を実行すると次のようになります:
This is a long line
short
Any other long line
シフトされる桁数は 'shiftwidth' オプションで設定します。これを 4 に変更するに
は次のようにします:
:set shiftwidth=4
"<" コマンドを使うと、選択範囲の左側にある空白を一つのシフト分だけ削除できま
す。このコマンドは選択範囲の左側にある空白の量によって制限されます。つまり、空
白がシフト量より少ない場合は、可能な範囲だけ空白が削除されます。
行の結合
"J" コマンドを使うと、選択範囲の行を一行に連結できます。つまり改行が削除されま
す。正確には、改行、行頭の空白、行末の空白、が一つの空白で置換されます
('joinspaces' オプションで動作を変更できます)。
さて、また同じ例を使って、今度は "J" を実行します:
This is a long line short Any other long line
"J" コマンドは矩形選択以外でも使えます。"v" や "V" で選択した場合も全く同じ動
作をします。
空白を変更したくない場合は、"gJ" コマンドを使ってください。
==============================================================================
10.6 ファイルの一部の保存と読み込み
メールを書いているとき、他のファイルを取り込みたいことがあるかもしれません。そ
れには ":read {filename}" コマンドを使います。指定したファイルの内容が現在行の
下にプットされます。
次の文章でやってみましょう。
Hi John,
Here is the diff that fixes the bug:
Bye, Pierre.
カーソルを二行目に移動し、次のコマンドを入力します:
:read patch
"patch" という名前のファイルが挿入され、次のようになります:
Hi John,
Here is the diff that fixes the bug:
2c2
< for (i = 0; i <= length; ++i)
---
> for (i = 0; i < length; ++i)
Bye, Pierre.
":read" コマンドに範囲指定すると、指定されたファイルが範囲指定された行の下に
プットされます。例えば、":$r patch" なら、"patch" の内容がファイルの末尾に追加
されます。
ファイルの先頭に読み込むにはどうすればいいでしょうか。それには、行番号 0 を指
定します。そのような行は実際にはないので、他のコマンドに指定するとエラーになる
かもしれませんが、このコマンドでは指定できます:
:0read patch
"patch" の内容がファイルの先頭にプットされます。
ファイルの一部だけ保存
ファイルの一部だけ保存するには、":write" コマンドを使います。範囲指定を省略す
るとファイル全体が保存されますが、範囲指定すると、指定した範囲の行だけが保存さ
れます:
:.,$write tempo
このコマンドで、現在行から最終行までが "tempo" に保存されます。ファイルが既に
存在している場合はエラーメッセージが表示されるので、間違ってファイルを上書きす
る心配はありません。ファイルを上書きしたい場合は、! を付けてください:
:.,$write! tempo
注意: ! は ":write" コマンドの直後に指定してください。間に空白を入れると、フィ
ルタコマンドになってしまいます。フィルタコマンドについては後で説明します。
ファイルに追記する
この章の最初の節で、複数の行をレジスタに集める方法を説明しました。同じように、
複数の行をファイルに集めることができます。まず、次のコマンドで最初の行を保存し
てください:
:.write collection
次に、二行目として保存したい行に移動し、次のように入力します:
:.write >>collection
新規ファイルとして保存するのではなく、">>" を使って、ファイルの末尾に追記する
ことを指示しています。あとは必要なだけこの操作を繰り返してください。
==============================================================================
10.7 テキストの整形
文章を入力しているとき、行が画面内に収まるように自動的に改行してくれたら便利で
すよね。そうするには、'textwidth' オプションを設定します:
:set textwidth=72
vimrc ファイルの見本 (vimrc_example.vim) で、テキストファイルが開かれたとき
にこのオプションが設定されるようにしていたのを覚えているでしょうか。したがっ
て、vimrc ファイルの見本をそのまま使っているなら、オプションは既に設定されてい
ます。現在の 'textwidth' の設定を確認するには、次のようにします:
:set textwidth
これで、行が 72 文字より長くなった行が改行されるようになりました。ただし、行の
途中からテキストを挿入したときや、単語削除をしたときは、行が 72 文字よりも長く
なったり短くなったりします。既存の文章が自動的に再整形されたりはしません。
現在の段落を整形するには、次のコマンドを使います:
gqap
これは "gq" というオペレータで始まるコマンドです。次に "ap" というテキストオブ
ジェクトが指定されています。これは "a paragraph" (一つの段落) という意味です。
段落は、空行で区切られたテキストです。
Note:
空行 (改行文字だけの行) と空白行 (空白文字だけの行) は違います。段落の
区切りは「空行」だけです。見た目では気づきにくいので注意!
"ap" 以外のテキストオブジェクトや、移動コマンドも指定できます。段落が正しく分
割されているなら、次のコマンドでファイル全体を整形できます:
gggqG
これは、"gg" で一行目に移動し、"gq" で整形オペレータを指定、"G" でファイル末尾
までジャンプしています。
段落の区切りが明確でない場合は、手動で行を選択して整形してください。整形したい
範囲の最初の行に移動し、"gqj" コマンドを使います。現在行と次の行が整形されま
す。現在行が短い場合は、次の行の単語が現在行に移動します。現在行が長い場合は、
現在行の単語が次の行に移動します。カーソルは次の行に移動しているので、"." でコ
マンドを再実行できます。あとは必要なだけ繰り返してください。
==============================================================================
10.8 大文字/小文字の変換
"section header" という小文字のテキストがあります。これを、"section" だけ大文
字にするには、"gU" オペレータを使います。カーソルを先頭に移動して、コマンドを
実行してください:
gUw
section header ----> SECTION header"gu" オペレータで小文字に変換できます:
guw
SECTION header ----> section header"g~" を使うと、大文字と小文字を切り替えることができます。今説明したのは全てオ
ペレータなので、移動コマンドやテキストオブジェクトやビジュアルモードと組み合わ
せることができます。
オペレータを行に適用するには、オペレータを二回繰り返してください。例えば、"d"
は削除オペレータなので、"dd" で一行削除になります。同じように、"gugu" で行全体
が小文字になります。もっと短く、"guu" でも構いません。"gUgU" は "gUU"、"g~g~"
は "g~~" と短縮できます。例:
g~~
Some GIRLS have Fun ----> sOME girls HAVE fUN==============================================================================
10.9 外部プログラムを使う
Vim には強力なコマンドがたくさんあるので何でもできますが、外部プログラムを使っ
た方がもっときれいで高速に処理できる場合もあります。
"!{motion}{program}" コマンドを使うと、ファイルの一部を、外部プログラムでフィ
ルタすることができます。つまり、{program} で指定したプログラムが実行され、
{motion} で指定した範囲のテキストがプログラムに入力され、指定された範囲のテキ
ストがプログラムの出力で置き換えられます。
UNIX のフィルタに馴染のない方にはわかりにくいと思うので、例を交えて説明します。
sort コマンドはファイルの中身をソート (並べ替え) するコマンドです。次のコマン
ドを実行すると、ソートされていない input.txt の中身が整列され、output.txt に保
存されます。(この例は UNIX でも Microsoft Windows でも動作します)
sort <input.txt >output.txt
さて、同じことを Vim でやってみましょう。1 行目から 5 行目までをソートしてみま
す。カーソルを一行目に移動して、次のコマンドを実行します:
!5G
"!" はフィルタを実行するためのコマンドです。次に、移動コマンドを実行し、フィル
タに渡す範囲を指定しています。"5G" は 5 行目に移動するコマンドなので、1 行目
(現在行) から 5 行目までがフィルタの範囲として指定されます。
カーソルが画面の一番下に移動し、! プロンプトが表示されるので、フィルタプログラ
ムの名前を入力してください。この場合なら "sort" ですね。したがって、コマンドは
全部で次のようになります。
!5Gsort<Enter>
コマンドを実行すると、最初の五行が sort プログラムで処理され、元のテキストが、
プログラムの出力で置き換えられます。
line 55 line 11
line 33 line 22
line 11 --> line 33
line 22 line 44
line 44 line 55
last line last line
"!!" コマンドを使うと、現在行をフィルタできます。Unix では "date" コマンドで現
在の日時を出力できるので、"!!date<Enter>" で現在行を "date" の出力で置き換える
ことができます。これはファイルに日付を挿入するのに便利です。
Note: "!cmd" (例: ファイル範囲なしで使用する) と "{range}!cmd" には違いがあり
ます。前者は単に外部コマンドを実行し、Vim は出力を表示しますが、後者はフィル
ターを通して {range} 行をフィルターし、その範囲をフィルターコマンドの結果で置
き換えます。詳細については、:! および :range! を参照してください。
うまく動作しない場合
シェルを起動し、テキストを入力し、出力を取り込むためには、シェルが正しく実行で
きるように設定されている必要があります。フィルタ処理に問題がある場合は、以下の
オプションを確認してください。
'shell' 外部プログラムを実行するために使われるプログラムの指定
'shellcmdflag' シェルにコマンドを渡すための引数指定
'shellquote' コマンドを囲むためのクォート文字
'shellxquote' コマンドとリダイレクトを囲むためのクォート文字
'shelltype' シェルの種類 (Amiga専用)
'shellslash' ファイル名のバックスラッシュをスラッシュにする
(MS-Windows 系専用)
'shellredir' コマンドの出力をファイルに保存するために指定する文字列
Unix では、設定する必要はほとんどありません。なぜなら、おそらく sh 系か csh 系
のシェルが使われているからです。Vim は 'shell' に "csh" という文字列が含まれて
いるかどうかでシェルの種類を判断し、関連したオプションを自動的に設定します。
しかし、MS-Windows ではいろんなシェルがあるので、フィルタを動作させるためには、
オプションを設定する必要があるかもしれません。詳しくはオプションのヘルプを参照
してください。
コマンドの出力を読み込む
カレントディレクトリの内容を読み込むには、次のようにします。
Unix系:
:read !ls
MS-Windows系: :read !dir
"ls" や "dir" コマンドの出力が取り込まれ、カーソルの下に挿入されます。これは
ファイルの読み込みに似ていますが、"!" を使ってコマンドを指定している点が違いま
す。
コマンドに引数を指定することもできます。出力をプットする場所を指定することもで
きます:
:0read !date -u
これはファイルの先頭に現在の日付と時間を UTC 形式で挿入します ("-u" 引数が使え
る date コマンドが必要ですよ。当たり前ですが...)。Note: "!!date" が現在行を置
き換えるのに対して、":read !date" は行を挿入するという点が違います。
コマンドにテキストを入力する
Unix の "wc" コマンドは単語を数えることができます。編集中のファイル内の単語を
数えるには、次のようにします:
:write !wc
これは上述の write コマンドと似ていますが、"!" を使って外部プログラムを指定し
ている点が違います。テキストがコマンドの標準入力に渡され、次のような結果が表示
されます:
4 47 249
"wc" コマンドは冗長なメッセージを出力しません。この出力は、行数が 4、単語数が
47、文字数が 249 であることを示しています。
次のような間違いに気をつけてください:
:write! wc
これはカレントディレクトリの "wc" というファイルに強制上書きするコマンドです。
空白は重要ですよ!
画面の再描画
外部プログラムがエラーを起こした場合、画面がめちゃくちゃになってしまうことがあ
ります。Vim は必要だと思われる最小限の領域だけを再描画しますが、他のプログラム
の出力内容を完全に把握することはできません。次のコマンドで画面を再描画できま
す:
CTRL-L
==============================================================================
次章: usr_11.txt クラッシュからの復帰
Copyright: see manual-copyright vim:tw=78:ts=8:noet:ft=help:norl: