FreeBSD vi 活用概論第1
Last Update (2010/03/27 01:04:46)
viはUNIXの黎明期から存在し、今なお使い続けられているすごいエディタである。
(ちなみに、本当の黎明期にはexというラインエディタが使われていた。MS-DOS ver. 3.x の EDLIN みたいな行編集エディタだったようだ。)
UNIXと名前のつくものなら、、emacs/mule/nemacsはインストールされていなくともviは必ずあるといっても過言ではない。
私は普段mule派なのだが、muleがインストールされる前の状態のシステム設定を行うときや、わざわざ重いmuleを起動するまでもない時にはviを利用している。
ここでは、必要最小限のviの使い方を紹介する。
- viには挿入モード(普通にテキストを入力するモード)とコマンドモード(カーソル移動や検索や置換などの操作を行うモード)がある。
- vi起動直後はコマンドモードになっており、コマンドモードから挿入モードに移行するには、a または i とタイプする。
- a --- カーソルの右側から挿入モードに移行する。(appendの意味だろう)
- i --- カーソルの左側から挿入モードに移行する。(insertの意味だろう)
- 挿入モードでタイプミスした場合は、Backspaceが利用できる。
画面表示上では削除できていないように見えるが、うまく消えているので安心してほしい。
- 挿入モードからコマンドモードへ移行するには、ESCキーを押す。
- コマンドモードでは、以下のコマンドを覚えておけばとりあえずOKだ。
- k --- カーソル上移動
- j --- カーソル下移動
- h --- カーソル左移動 (hjklの中で、一番左にあるからだろう)
- l --- カーソル右移動 (hjklの中で、一番右にあるからだろう)
- x --- カーソル位置の文字を削除
- コマンドモードで : をタイプすると、画面下にカーソルが移動する。
以下では、画面下にカーソルが移動して行入力可能になった状態を便宜的に「行コマンドモード」と呼ぶことにする。
- 行コマンドモードで wリターンでセーブになる。(writeの意味だろう)
- 行コマンドモードで qリターンでvi終了になる。(quitの意味だろう)
- 行コマンドモードでは、複数のコマンドをいっぺんに行うことが可能だ。
セーブして終了するなら、行コマンドモードから wqリターンで良い。
- 行コマンドモードで q!リターンで、ファイルをセーブせずにvi終了になる。
毎回「行コマンドモード」と書くのも面倒なので(^^;)、: を入力して行コマンドモードにしてから入力するコマンドは、:w のように記載することにしよう。
上で紹介した4つのコマンドをもう一度簡略記法で書いておく。
- :wリターン --- ファイルにセーブ
- :qリターン --- vi終了
- :wqリターン --- ファイルにセーブしてviを終了する。
- :q! --- ファイルをセーブせずにvi終了
以上で、最小限のviコマンド(約10個)は終了だ。
/etc/rc.confの修正くらいなら、以上のコマンドを駆使して何とかなるだろう。
もし、今挿入モードになっているのか、コマンドモードになっているのか、行コマンドモードになっているのかを忘れてしまったら、とりあえずESCキーを連打しよう。
そうすることで、確実にコマンドモードになるはずだ。
関連性の無い妙なコマンドが沢山あるように感じるので、覚えるのがたいへんだと思う。
必要なコマンドから徐々に覚えていくと良いだろう。
FreeBSDページの目次に戻る
上で紹介した level 1 のキーだけでもほとんどの修正作業は可能だが、やはり多少不便である。
viを使っていて欲が出てきたら、以下のコマンドを覚えると良い。
以下に示すコマンドは、すべてコマンドモードから入力するものだ。
- A --- 行の最後に移動して挿入モードにする。(aの強化版)
- I --- 行の先頭に移動して挿入モードにする。(iの強化版)
- o --- カーソルの1行下に新しい行を作り、挿入モードにする。(other lineの略かな?)
- r --- カーソル位置の1文字を次に入力する1文字と交換する。
- Ctrl F --- 1画面スクロールアップ
- Ctrl B --- 1画面スクロールダウン
- J --- カーソルより後ろにある改行コードを削除する。
要するに、二つの行を連結するわけだ。
- 0 -- 行の先頭にカーソル移動
- $ -- 行の最後にカーソル移動
- 1G -- ファイルの先頭(1行目)にカーソル移動
- G -- ファイルの最後にカーソル移動
これくらい知っていれば、緊急避難的にviを利用するには十分だろう。
ちなみに、Ctrl FやCtrl B, j, k, Gなどのキーバインドは more や less でも採用されている。
覚えておくと意外なところで便利だ。
FreeBSDページの目次に戻る
ここでは、検索コマンド、カット&ペーストコマンドなどを紹介する。
ここにあるコマンドまでを覚えれば、結構便利に vi を利用できるようになるはずだ。
- / --- 順方向検索文字を指定。
コマンドモードから / を押すと、画面下の行入力モードになる。
ここで、検索したい文字列を入力してリターンを押すと、カーソルが検索文字列の所まで移動する。
画面下に向かって検索する。
- ? --- 逆方向検索文字を指定。
コマンドモードから ? を押すと、画面下の行入力モードになる。
ここで、検索したい文字列を入力してリターンを押すと、カーソルが検索文字列の所まで移動する。
画面上に向かって検索する。
- n --- 次検索を実行
/ や ? で検索文字を指定してある場合は、同じ検索文字を使って次検索を行う。
直前に / を行っていた場合には、順方向に次検索を行い、直前に ? を行っていた場合には逆方向に次検索を行う。
- N --- 逆方向次検索を実行
/ や ? で検索文字を指定してある場合は、同じ検索文字を使って逆方向へ次検索を行う。
直前に / を行っていた場合には、逆方向に次検索を行い、直前に ? を行っていた場合には順方向に次検索を行う。
- :行番号 -- 指定した行位置に移動
: で行入力モードになるので、数字を入力してリターンを押すと、指定した行にカーソルが移動する。
- yy -- カーソルのある行をバッファにコピーする。
- dd -- カーソルのある行を削除してバッファにコピーする。
- p -- カーソルのある行の下の行の先頭にバッファの内容を追加する。
- P -- カーソルのある位置にバッファの内容を追加する。
私が知っているviのコマンドは、だいたいこのあたりまでである(汗;)。
これ以上複雑な操作をする場合は、muleを使ってしまうのだった。
FreeBSDページの目次に戻る
viの真価は、コマンドの組合せでさらに柔軟なテキスト編集機能を提供している所にある。
例えば dd (カーソルのある行を削除してバッファにコピー)として紹介したコマンド d だが、以下のように組み合わせて指定することができる。
jman vi とすると、 d コマンドの説明として下記のように表示される。
[buffer] [count] d motion
範囲指定した文書を削除します。
つまり、dコマンドは
- "a d --- コマンドモードから、バッファ名 'a' に d コマンドで削除された文字を入れる。
バッファ名として利用可能なのは a 〜 z の 26個だ。
- 数字 d -- コマンドモードから 数字 の回数だけ d コマンドを実行。
- d$ -- コマンドモードから カーソル位置から行の最後までの文字を削除してバッファにコピー。
$ は行の最後へカーソルを移動するコマンドなので、d$ と組み合わせると行の最後まで削除という意味になる。
- d0 -- コマンドモードから カーソル位置から行の先頭までの文字を削除してバッファにコピー。
0 は行の先頭へカーソルを移動するコマンドなので、d0 のように組み合わせると行の先頭まで削除という意味になる。
- d3j -- コマンドモードから、カーソル位置から3行下までの文字を削除してバッファにコピー。
3j というコマンドは j (カーソルを1行下に移動する)コマンドを3回実行するという意味になる。
d3j のようにカーソル移動コマンドと組み合わせることで、カーソル位置から自在に削除できることになる。
- d/abc -- コマンドモードから、abcと言う文字列を順方向に検索して、発見した所まで削除してバッファにコピーする。
/abc は順方向に abc という文字列を検索するコマンドだ。
これと、dコマンドを組み合わせている。
のように、組み合わせて利用できるのだ。
ついでに書いておくと、 yy コマンド (コマンドモードから、カーソルのある行をバッファにコピーする) として紹介した y コマンドも、dコマンドと同じような指定ができたりする。
つまり、 y3j でカーソル位置から3行下までの文字をバッファにコピーする、という意味になるのだ。
また、ファイルの最後の行に移動するコマンドとしてvi 基本キーバインド - level 1で紹介した「G」コマンドだが、このコマンドの前には行番号を指定できる。
「100G」などと入力すると、100行目に移動するのだ。
コマンドの組み合わせを自由自在に使いこなせるようになったら、あたなは無敵のvi使いとして恐れられるようになるだろう。
FreeBSDページの目次に戻る
ここでは、私が覚えている途中のviキーバインドを紹介する。
- f --- 次に入力される1文字をカーソルから右方向に検索して検索文字の上にカーソル移動
fcなどと入力すると、カーソル位置から右に文字 c を検索して、発見したら c の上でカーソルが止まる。
このコマンドは一行の中でしか検索しない。
- F --- 次に入力される1文字をカーソルから左方向に検索して検索文字の上にカーソル移動
検索方向が違うが、他は f コマンドと同じ。
- t --- 次に入力される1文字をカーソルから右方向に検索して検索文字の一つ手前にカーソル移動
tcなどと入力すると、カーソル位置から右に文字 c を検索して、発見したら c の一つ左でカーソルが止まる。
このコマンドは一行の中でしか検索しない。
- T --- 次に入力される1文字をカーソルから左方向に検索して検索文字の一つ手前にカーソル移動
検索方向が違うが、他は t コマンドと同じ。
- ;(セミコロン) --- 最後に使った f, F, t, T コマンドを繰り返す
- ,(カンマ) --- 最後に使った f, F, t, T コマンドを逆方向に繰り返す
- Ctrl E --- 画面を前方へ一行分スクロールさせる
- Ctrl Y --- 画面を後方へ一行分スクロールさせる
一行だけスクロールさせたい場合に便利だ。
- m --- 次に入力する1文字をマーク文字として、現在のカーソルがある位置をマーク文字に記録
emacsで言うところのSet-Mark-Commandみたいなものだ。
mを入力した後にマーク文字(たとえば a とか)を入力すると、現在カーソルがある位置を a というマーク文字で記憶する。
マーク文字として利用できるのは、a 〜 z の26文字だ。
- '(クォート) --- 次に入力するマーク文字のマーク位置の行の、空白以外の最初の文字がある場所までカーソル移動
上の操作で覚えたカーソル位置へカーソルを移動する。
上の例では a という文字をマーク文字として使っているので、 'a と入力するとさきほど覚えさせたマーク位置までカーソルが移動する。
- `(バッククォート) --- 次に入力するマーク文字のマーク位置までカーソル移動
上の操作で覚えたカーソル位置へカーソルを移動する。
上の例では a という文字をマーク文字として使っているので、 `a と入力するとさきほど覚えさせたマーク位置までカーソルが移動する。
上で示したのコマンド ' と異なり、こちらはカーソルのカラム位置も復元される。
余談だが、セットマークコマンドとマーク位置にカーソル移動コマンドがあるので、viでもemacs風味にカット&ペーストできる。
- maコマンドで、カーソル位置記憶
- カーソル移動して範囲指定
- y`a で、先程のカーソル位置までバッファにコピー
- d`a で、先程のカーソル位置まで削除してバッファにコピー
- カーソル移動してペースト位置まで移動
- P でカーソル位置にバッファの内容をペースト
- p でカーソルがある行の次行にバッファの内容をペースト
ここまで覚えると、viが便利なものになってきたような気がする。(^^)
FreeBSDページの目次に戻る
ここでは、viでキーボードマクロを定義する方法を紹介する。
ここで言うキーボードマクロとは、ある決まった操作を繰り返して行いたい場合に特定のキー操作(コマンド)を覚えておいて、後で同じ操作を再度実行できるというものを想定している。
viでは、自分で一連の操作コマンドを定義したい場合には :map コマンドを利用する。
:map キー 定義内容
などとすると、とあるコマンドに一連のコマンドを割り当てることができる。
たとえば
:map v dwElp
などと定義しておくと、viのコマンドで v を押すとカーソル位置にある単語と、その右側にある単語を入れ換えることができるようになる。
また、:map のみ入力すると、現在定義されているコマンドの一覧が表示される。
デフォルトのviで、コマンドモードで利用されていない(未定義)のコマンド文字には
- g q v K V
- ^A ^K ^T ^W ^X ^O (かんなを利用するjelvisやjvimでは ^O はかんな起動に使っている)
- _ * ¥ = (=はLispモードでは利用されている)
というものがあるらしいので、普段は g か v あたりをmapで利用することになるだろう。
便利なことに(ある意味では恐ろしいことに)、既に定義されているコマンドも :map で再定義できるようなので、 :map x l などとすると、 x で左カーソル移動などというわけのわからない動作をさせることもできるようだ。
FreeBSDページの目次に戻る
ここでは、viで置換を行う方法を紹介する。
余談:
普通のエディタの入門書では、検索と置換はだいたいとなりに書いてあるというのが相場だ。
ただ、私の場合はまじめに置換を行う場合はmuleを使ってしまうので、viの置換を覚えるのがずいぶんと遅くなった。
そんなわけで、置換コマンドはlevel 7にて初登場ということになった。
- :s/old/new/ -- oldという文字列をnewという文字列に置き換える。
ただし、最初に発見したものを一度だけ置き換える。
- :s/old/new/g -- oldという文字列をnewという文字列に置き換える。
こちらの場合は、oldという文字列を発見した数だけ置き換えが実行される。
ただし、このままではカーソルのある行のみが影響範囲となる。
実は、sコマンドも影響範囲を指定することができる。
- :1,5s/old/new/g -- 1行目から5行目までにあるoldという文字列をnewという文字列に置き換える。
- :1,$s/old/new/g -- 1行目からファイルの最後の行までにあるoldという文字列をnewという文字列に置き換える。
早い話がファイル中のすべてのoldをnewに置換する。
$はファイルの最後の行をあらわしている。
- :%s/old/new/g -- ファイル中にあるoldという文字列をnewという文字列に置き換える。
行入力モードでの%は「現在編集中のファイル名」を意味しているので、ファイル全部を置換することになる。
viにも置換する前に確認する方法がある。
s(置換)コマンドのオプション指定部分(一番右側)にcをつけると、置換前に確認してくるようになる。
- :s/old/new/gc -- 置換を実行する前に、確認してくる。
置換するなら y を、置換しないなら n を、置換を途中でやめる場合は q を押す。
上の例では、1行の中しか置換しない。
ファイルの内部全部を置換する場合は「:%s/old/new/gc」とする。
「vi入門」には、置換する場合は y [return] を押すと書いてあった。
FreeBSDで標準的にインストールされるviはnviなので、本物のviとは動作が違うのかも知れない。
上で紹介している一括置換コマンドとはちょっと違うが、現在のカーソル位置からの置換コマンドもある。
- cw -- 現在のカーソル位置にある単語を削除し、挿入モードになる。
ESC で挿入モードを終了する。
- c$ -- 現在のカーソル位置から行の最後までを削除し、挿入モードになる。
ESC で挿入モードを終了する。
上の二つの例は「c」という置換入力コマンドに「w」や「$」というカーソル移動コマンドを組み合わせたものだ。
cwは比較的よく使うので、覚えておくと便利だ。
FreeBSDページの目次に戻る
ここでは、viでマクロを定義する方法を紹介する。
mapコマンドはvi コマンド map - level 6で紹介したが、今回はバッファを使ったマクロ定義方法である。
何度も同じような作業を繰り返していると、ついつい眠くなるものだ。
決まりきった作業なら自動化を考えるべきだろう。
そんなわけで、ある程度まとまった操作を一発でできるようにする方法を示す。
バッファの内容は保存されないので、viを終了したら折角のマクロが消えてしまう。
傑作マクロができたら、保存したくなるのが人情だ。
だが、viにはバッファの内容を直接ファイルに保存する方法はないみたいだ。
一応、下のようにすればバッファの内容を保存できるが結構面倒だ。
- :n bufferfile -- バッファの内容を保存するためのファイルを開く。
- :put a -- バッファ「a」の内容を現在行に追加する。
- :write -- ファイルを保存する。
- :n bufferfile -- バッファの内容を保存したファイルを開く。
- :yank a -- 現在行をバッファ「a」にコピーする。
そのうちに、 ‾/.exrc に何か指定する方法を調査する予定だ。
FreeBSDページの目次に戻る
以上で入門編は終了することにして、以下ではコマンドの種類ごとに編集して vi のコマンドを紹介する。
viに慣れて来たら、コマンドは種類ごとに分類されているほうが探しやすい。
- h
- カーソルを左に1文字移動
- j
- カーソルを下に1文字移動
- k
- カーソルを上に1文字移動
- l
- カーソルを右に1文字移動
- w
- カーソルを次の単語の先頭文字の上に移動
- b
- カーソルを前の単語の先頭文字の上に移動
- e
- カーソルを単語の末尾文字の上に移動
- 0
- カーソルを行の先頭に移動
- $
- カーソルを行の最後に移動
- :n
- 行番号 n にジャンプ
- G
- ファイルの最終行にジャンプ
FreeBSDページの目次に戻る
- CTRL F
- 順方向の画面にスクロール
- CTRL B
- 逆方向の画面にスクロール
- CTRL D
- 順方向の画面に半画面分スクロール
- CTRL U
- 逆方向の画面に半画面分スクロール
- CTRL E
- 順方向の画面に1行分スクロール
- CTRL Y
- 逆方向の画面に1行分スクロール
- z.
- カーソルのある行を画面の中央に表示するようにスクロール
FreeBSDページの目次に戻る
- /
- 順方向に検索
- ?
- 逆方向に検索
- n
- 直前の検索を同じ方向に繰り返す
- N
- 直前の検索を逆方向に繰り返す
FreeBSDページの目次に戻る
プログラムを書く時に便利なviの設定を記載する。
viは起動時に ‾/.exrc という設定ファイルを読み込む。
FreeBSDの標準viはviクローンの中でも nvi というプログラムなので、‾/.nexrcという設定ファイルも読み込む。
以下の設定は ‾/.nexrcに書いておくと便利かも。
- set autoindent
- 自動インデントする。
前の行にあわせて、改行を入力した時にインデントしてくれる。
- set exrc
- ホームディレクトリの.exrcではなく、カレントディレクトリの.exrcを読み込むようにする。
各ディレクトリで設定が違う場合(TABの幅とか)は便利。
- set shiftwidth=8
- << コマンドや >> コマンドでインデント移動する量を指定
- set tabstop=8
- TABを何カラムに設定するかを指定する。
- set showmatch
- プログラム中の( ) や { } の対応を表示してくれるように設定する。
- set number
- 左側に行番号を表示するようにする。
- set nonumber
- 左側に表示されていた行番号を表示しなくする。
X11上でコピー&ペーストする場合に便利(笑)
なお、上のコマンドは .exrc に書くだけではなく、 viの「行入力モード」からも入力できる。
Copyright(c) 1996,97,98,99,2000,01,02,03,04,05,06,07,08,09 George(小濱 純). All rights reserved.
私の作成したページへのリンクはご自由にどうぞ。
このページに間違いや要望などがありましたら
george@yk.rim.or.jp まで御連絡ください。
メール本文に 6020-5440-3372 と書いて頂くと、SPAMフィルタを通過できます(2009-06-14から2009-12-31まで)。
home:
<george@yk.rim.or.jp>
or
<george@ceres.dti.ne.jp>
(I am using white list SPAM filter. To avoid it, please write 6020-5440-3372 in mail body. This key word is valid since 2009-06-14 until 2009-12-31.)