応用編
ここでは、行数を指定しての削除や、行のコピー・移動、文字列の置き換えについて説明します。
コマンドの繰り返し
文字削除の x コマンドで、文字を消す前に、数字を入力すると、その文字数分削除することになります。"10x" とタイプすると、カーソルから 10 文字削除されます。
同様に、dd コマンドの前に数字を入力すると、入力した行数削除されます。
カーソル移動
カーソルの移動は、基本編のカーソル移動 以外にも便利なコマンドがあります。
| コマンド | 説明 |
|---|---|
| 0 | 行の先頭にカーソル移動 |
| ^ | 空白文字以外の行の先頭にカーソル移動 |
| $ | 行の末尾にカーソル移動 |
| w | 次の語の先頭にカーソル移動 |
ed コマンド
ed とは、ラインエディタのことです。その昔、テキストの編集は行単位での編集でした。今のように長大なプログラムではなかったので、なんとか編集することができました。この ed コマンドを拡張した ex コマンドがあり、ex コマンドと、vi は実体が同じです。現在も、vim と ex の実体は同じであり、vim から ex の編集コマンドを使うことができます。
ed のプロンプトが ':' だったので、vi でも ':' で始まるコマンドは、ed のコマンドになります。
ちなみに、ed でテキストを挿入する時、行頭で '.'(ピリオド)のみで改行すると、挿入モードを終了します。
: コマンドの形式
:[対象][コマンド][パラメータ]
対象は、コマンドを適用する対象(範囲)を指定します。行番号及び、特殊文字で指定します。行番号は最初の行が 1 になります。行にマークを付け、行番号の代わりに使うことができます。
| 対象 | 説明 |
|---|---|
| 省略 | カーソルのある行を対象にします。 |
| . | カーソルのある行を対象にします。 |
| 行番号 | 行番号の行を対象にします。 |
| 行番号1,行番号2 | 行番号1 〜 行番号2 の範囲を対象にします。 |
| $ | 最終行を対象にします。 |
| % | 全ての行を対象にします。 |
| 'a,'b | a とマークした行から b とマークした行までを対象にします。 |
マークは、m<アルファベット 1 文字> でカーソル行にマークを付けます。例えば、 a とマークを付けるには、ma とタイプします。この時、画面に変化はありません。小文字と大文字は区別されます。同じ文字でマークした場合、最後にマークした行が有効です。行番号の代わりにマークを使うには、'(シングルクォート)を使い、'<マークに使用したアルファベット 1 文字> のように書きます。
私がよく使うコマンドを次に示します。
| コマンド | 説明 |
|---|---|
| d | 行の削除 |
| s | 文字列の置き換え |
| t | 行のコピー |
| m | 行の移動 |
| w | ファイルへの書き出し |
パラメータは、コマンドによって違います。コマンドの説明を読んでください。行の削除のようにパラメータの必要ないものもあります。
vi のコマンドと、ed のコマンドで同じ機能のコマンドがあります。どちらを使ってもいいのですが、ed のコマンドは強力です。行のコピーなどは、ed のコマンドを使っているので、vi のコマンドは説明を省略しています。
指定行へのジャンプ
任意の行へジャンプするには、次のようにします。
:行番号ENTER
記号や、マークを行番号として使えます。
以下に行へのジャンプの例を示します。
| コマンド | 説明 |
|---|---|
| :10ENTER | 10 行目にカーソルを移動 |
| :+5ENTER | 5 行下にカーソルを移動 |
| :-3ENTER | 3 行上にカーソルを移動 |
| :$ENTER | 最終行にカーソルを移動 |
| 'a | a とマークした行に移動(:'aENTERでも同じ) |
行の削除
行を削除する ed コマンドは、d です。パラメータはありません。
:[対象]dENTER
以下に削除の例を示します。
| コマンド | 説明 |
|---|---|
| :dENTER | カーソル行を削除 |
| :3dENTER | 3 行目を削除 |
| :6,10dENTER | 6 行目から 10 行目までを削除 |
| :.,+10dENTER | カーソル行から 10 行下までを削除 |
| :-5,.dENTER | 5 行前からカーソル行までを削除 |
| :'a,'bdENTER | a とマークした行から b とマークした行までを削除 |
| :%dENTER | 全ての行を削除(:1,$dENTER でも同じ) |
.,+10 はカーソル行と、その下 10 行の 11 行になることに注意してください。11 行削除されます。
+10 や -5 は、.+10, .-5 と書いてもいいです。.+10 とは、カーソルのある行の 10 行下という意味です。マークした行も同じで、'a+10 とすると、a とマークした行から 10 行下ということになります。
文字列置き換え
文字列の置き換えは、ed の s コマンドになります。
:[対象]s/文字列1/文字列2/[g]ENTER
対象となる各行について、文字列1 を文字列2 に置き変えます。g オプションを付けないと、対象となる各行の最初に見つけた文字列1 だけを置き換えます。g オプションを付けると、対象行の全ての文字列1 を文字列2 に置き換えます。カーソルは最後に置き換えた文字列のある行に移動します。
以下に文字列置き換えの例を示します。
| コマンド | 説明 |
|---|---|
| :s/文字列1/文字列2/ENTER | カーソル行で最初に見つけた文字列1 を文字列2 に置き換える |
| :s/文字列1/文字列2/gENTER | カーソル行の全ての文字列1 を文字列2 に置き換える |
| :%s/文字列1/文字列2/gENTER | ファイル内の全ての文字列1 を文字列2 に置き換える |
| :10,20s/文字列1/文字列2/gENTER | 10 行目から 20 行目の全ての文字列1 を文字列2 に置き換える |
| :'a,.s/文字列1/文字列2/gENTER | a とマークした行からカーソル行の全ての文字列1 を文字列2 に置き換える |
| :'a,'bs/文字列1/文字列2/ENTER | a とマークした行から b とマークした行の各行で最初の文字列1 を文字列2 に置き換える |
置き換え対象の文字列が見つからない行に対しては何もしません。一度も置き換えが発生しない場合でも、エラーになりません。
文字列に '/'(スラッシュ)を含む場合、'\'(バックスラッシュ)でエスケープするか、s コマンドの次の記号(/)を変え、:s#文字列1#文字列2# のようにします。s コマンドの次の記号が、文字の区切り記号になるのです。
行のコピー
行のコピーは、ed の t コマンドになります。
:[対象]tコピー先行番号ENTER
コピー先行番号は省略できません。
以下に行のコピーの例を示します。
| コマンド | 説明 |
|---|---|
| :t.ENTER | カーソル行をカーソル行の下にコピーする |
| :8,10t.ENTER | 8 行目から 10 行目をカーソル行の下にコピーする |
| :'a,.t.ENTER | a とマークした行からカーソル行までをカーソル行の下にコピーする |
| :'a,'a+3t.ENTER | a とマークした行から 4 行分をカーソル行の下にコピーする |
| :'a,'bt.ENTER | a とマークした行から b とマークした行までをカーソル行の下にコピーする |
| :t0ENTER | カーソル行を先頭行にコピーする |
| :.,+3t$ENTER | カーソル行から 4 行分を最下行にコピーする |
| :.,+1t-5$ENTER | カーソル行と次の行を 5 行前にコピーする |
行の移動
行の移動は、ed の m コマンドになります。元を残さないだけで、コピーと同じ使い方をします。
:[対象]m移動先行番号ENTER
以下に行の移動の例を示します。
| コマンド | 説明 |
|---|---|
| :m-2ENTER | カーソル行を前の行と入れ替える |
| :m+1ENTER | カーソル行を下の行と入れ替える |
| :8,10m.ENTER | 8 行目から 10 行目をカーソル行の下に移動する |
| :'a,'a+3m.ENTER | a とマークした行から 4 行分をカーソル行の下に移動する |
| :'a,'bm.ENTER | a とマークした行から b とマークした行までをカーソル行の下に移動する |
| :m0ENTER | カーソル行を先頭行に移動する |
| :.,+3m$ENTER | カーソル行から 4 行分を最下行に移動する |
| :.,+1m-5$ENTER | カーソル行と次の行を 5 行前に移動する |
ファイルへの書き出し
ファイルへの書き出しは、ed の w コマンドになります。
:[対象]w[!] [ファイル名]ENTER
ファイル名の前には半角空白を入れます。
! を付けていない場合は、読み込み専用のファイルに対しては書き出しません。! を付けると、強制書き出だしになります。読み取り専用のファイルに対しても書き込もうとします。自分が所有するファイルであれば書き出せます。
ファイル名を省略すると、現在編集中のファイルに書き出します。ファイル名を指定すれば、そのファイルに書き出します。
以下にファイル書き出しの例を示します。
| コマンド | 説明 |
|---|---|
| :wENTER | 現在の内容を現在開いているファイルに書き出す |
| :w newfileENTER | 現在の内容を newfile に書き出す |
| :1,10w AAAENTER | 1 行目から 10 行目までを AAA というファイルに書き出す |
| :'a,'bw listENTER | a とマークした行から b とマークした行までを list というファイルに書き出す |
これでかなり効率的に編集が出来るようになると思います。しかし、vi の実力は、これだけではありません。正規表現を使った置き換えを使ってこそ、vi マスターと言えるでしょう。正規表現を使った置き換えについては、高度な編集 で説明しています。