テキストエディタ vi

設定作業とテキストエディタ

Unix上で動く色々なプログラムの設定ファイルは全てテキストファイルで できている。これを編集するにはテキストエディタを使う。ただし、 どんなテキストエディタでもよいというわけではなく、「システムがトラブルに 陥ったとき(HDD故障など)にも使えるエディタ」を普段から使用しておく ことが重要である。とくに、自分以外のユーザも利用するマシンでは、 「調子悪くなったらフォーマットして再インストール」というわけには いかないので、追加アプリケーションが全く使えないときでも作業できるよう OS標準のテキストエディタで作業できるようにしておく。

シングルユーザモード

Unixはマルチユーザ/マルチタスクを前提としているが、OS更新のような根幹 の設定作業のときにはシングルユーザモードに落とす。また、 ハードディスクの一部が壊れたときなどは、シングルユーザモードでしか 起動しないこともある。シングルユーザモードは HDDのうち、起動に必要な最低限のものだけをマウント(結合)した状態で 稼動する。

もっとも逆境に強いエディタは ed で、一昔前は管理者必修のエディタと されていたが、最近ではviが使えればほとんどのトラブル時に困らない。 viはedの拡張版なので、viを覚えていればedを覚えるのもたやすい。 viは教わらなければ全く使い方が分からないので最初のうちは戸惑うが、 機能が極端に少ないのでそこそこ使えるようになるのはあっという間である。

viの最低限の機能

ファイルを開いて編集して、保存(または破棄)終了する、まで 覚えればとにかく使える。

起動と終了

シェル上から、「vi ファイル名」として起動する。

% vi ファイル名

終了は、以下の3つを覚えておけばよい。

編集コマンド

以上の操作だけでファイルの編集操作は全て可能となる。

vi機能の体系

viは、起動すると「コマンドモード」になる。普通にタイプした文字は そのままコマンドとして機能する。iaを押すと 「挿入モード」に入り、ESCキーを押すまで、打ったキーがそのまま 文書中に入る。

コマンドモードで入力するコマンドは

の2種類に分かれている。各々のコマンド入力は

[数引数] コマンド

と入力する。数引数は、「直後のコマンドを何回繰り返すか」を 指定でき、数引数を省略すると 1回 を指定したものとなる。たとえば、

x

とだけタイプすると、1字だけ削除され、

5j

とタイプすると、jを5回タイプしたのと同じ結果になる(5行下に移動する)。

編集系コマンドの中には変更範囲を指定すべきものがある。それらは

編集コマンド 移動コマンド

を続けて入力する。タイプした編集コマンドをどの範囲まで適用するかが 直後の移動コマンドで移動する範囲で決まる。たとえば、dコマンド は「削除」を意味するコマンドで、カーソル位置から削除を始めることは決まっ ているが「どこまで」は決まっていない。直後に移動コマンドをタイプして「ど こまで」を確定させる。たとえば、

dl

は、lによって1字右に移動するので、カーソル位置の文字が 1字だけ削除される。また、移動系コマンドwは「1単語進む」 という意味なので、

dw

とすると、1単語分だけ削除される。bコマンドは「1単語戻る」 という意味なので、

d3b

とすると、カーソルから先頭方向に3単語分削除される。d3b3dbとやっても同じ結果となる。

以下にコマンド一覧を示す。ほぼ全てのコマンドは直前に数引数を 指定することで繰り返し数を指定できる。 表中のMCは移動系コマンドを意味する。

コマンドはたらき
a現在文字の後ろで挿入モードに移行。
A行の末尾で挿入モードに移行する。
b1単語戻る。
C-b1ページ戻る。
B空白のみを単語区切りとみなして1単語戻る。
cMC MCで移動する範囲までを変更対象として挿入モードに 移行する。ccとすると現在行全体を変更対象として挿入モードへ (Sと同じ)。一単語分変更するcwはよく使う。
Cカーソル位置から行末までを変更対象として 挿入モードに移行。数引数Nを指定すると さらにN-1行下まで変更対象に加える。
dMC MCで移動する範囲までを削除する。 ddとすると現在行全体を削除する。 一単語削除するdwはよく使う。
Dカーソル位置から行末までを削除する。 数引数Nを指定するとさらにN-1行下まで削除する。
C-d半画面分スクロールして進む。
e単語の末尾に移動。
Eeと同じだが空白のみを 単語区切りとみなす。
C-eカーソル位置はそのままで 1行スクロールアップ。
f文字現在行で文字を 探してその位置まで移動。
F文字現在行で文字を 逆方向に探してその位置まで移動。
C-f1ページ進む。
Gファイル末に移動。数引数Nを指定すると N行目に移動。1Gでファイル先頭へ。
C-g現在行の情報を表示。
h1字戻る。前の行には戻らない。
C-h1字戻る。
H画面の先頭へ。
iカーソル位置で挿入モードに移行。
I行の最初の非空白文字位置で挿入モードに移行。
j
C-j
1行下へ。
J次の行と結合。
k1行上へ。
l1字進む。次の行には進まない。
SPC1字進む。
L画面の最下行へ。
C-l画面を書き直す。
m文字文字レジスタに 現在位置を記憶(マーク)する(' または`で呼び出す)。
M画面の中央行へ。
C-m下の行の最初の非空白文字に移動する。
n/または ?での検索を繰り返す。
N/または ?での検索を逆方向に繰り返す。
o次の行を開いて挿入モードに移行。
O上の行を開いて挿入モードに移行。
pバッファの内容を後ろにペースト。
Pバッファの内容をペースト。
r文字カーソル位置の文字を 文字に置き換える。
R置換モード(上書きモード)に移行する (ESCで戻る)。
s1字を置き換える形で挿入モードに移行。
S現在行を置き換える形で挿入モードへ。
t文字現在行で 文字を探してその直前まで移動
T文字現在行で 文字を逆方向に探してその直前まで移動
C-u半画面分スクロールして戻る。
C-v(挿入モードで)次の入力文字をそのまま テキストとして挿入する。
w1単語進む。
W空白のみを区切りとみなして1単語進む。
x1字削除する。
X前の文字を削除する。
yMC MCで移動する範囲までをバッファに記憶する。 yyとすると現在行全体を記憶する(Yと同じ)。
Y現在行全体をバッファに記憶する。 数引数Nを指定するとまとめてN行記憶する。
C-yカーソル位置はそのままで 1行スクロールダウン。
ZZファイルが更新されていれば保存し viを終了する。
|数引数で指定した桁位置に移動する。
0行頭に移動する。
$行末に移動する。
%対応する括弧に移動する。
.直前のコマンドを繰り返す。
;f F t Tの行内文字検索を繰り返す。
,f F t Tの行内文字検索を 逆方向に繰り返す。
+
C-m
[Return]
1行下の 最初の非空白文字へ。
-1行上の最初の非空白文字へ。
'文字 文字レジスタに記憶された位置の行の最初の非空白文字に移動する。
`文字 文字レジスタに記憶された位置に移動する。
"文字 次に行なう削除/記憶の結果を文字レジスタに記憶させる。 記憶させたものは "文字p または "文字P で取り出せる。個人で設定するレジスタ には英字を利用する。レジスタ1〜9は「n回前に記憶した内容」 を自動的に保持しているので、過去に切り取った内容を取り出したいときは "2p などとする。取り出す内容がずれた場合はu でアンドゥして.で再取り出しする。"2u.u.u. と繰り返すと、過去に記憶した文字列を順に取り出せる。
/正規表現[Return] 正規表現を末尾方向に検索する。
?正規表現[Return] 正規表現を先頭方向に検索する。
z[Return]現在行を画面先頭に。
z.現在行を画面中央に。
z-現在行を画面最下部に
C-^別のファイルへ

exコマンド

viのコマンドモードで : (コロン)を押すと「exコマンドモード」 に入る。exとはviの前身のエディタで、文書の上にカーソルを表示したり 移動したりという機能がなく、あらゆる編集操作を専用の言葉で司令して 行なうものである。広々とした画面が使えなかった時代に主に利用した。

専用言語を使うので、見ればすぐ分かるようなちょっとした編集操作でも 難しい。その代わり、「口でいうのは簡単だが、実際にキーボードを操作して 修正するのはとても手間がかかる」ような処理が「口でいうのは簡単」な 時間で済んでしまう。

たとえば、以下のようなファイルがあるとする。

abcde@foobarco.jp
xyzw@yareyare-komatta.jp
nanashino@wakega-wakaran.jp
alien@dokonodareda.com
honyarara@pittashi-kankan.jp
hogehoge@fugafuga.jp
yamamoto@sub.yareyare-komatta.jp
kanamoto@mx.yareyare-komatta.jp
kankan@pittashi-kankan.jp
  :
 以下多数(100行とか1000行とか)

これにたいして、以下のような操作を普通のテキストエディタでやると たいへんである。

  1. yareyare-komatta.jp の人とはよく連絡を取るので そのアドレスの人だけ先頭に集めたい。

  2. pittashi-kankan.jp のドメインがなくなったので それらの人のアドレスを消したい。完全に消すのではなく 行の先頭に # マークを付けて無効化を意味するように 修正する。

  3. カーソルのある行から最後まではあまり使わないので 行頭に # をつけたい。

exコマンドを使ってこれらを一発で片付けよう。exのコマンドは基本的に

[対象範囲] コマンド

という形式で指定する。 以下のようなコマンドを使うことで上記操作が一気に編集できる。

  1. yareyare-komatta.jp の人とはよく連絡を取るので そのアドレスの人だけ先頭に集めたい。

    :を押してexモードに移行してから 以下のようにタイプすればよい。

    :g/yareyare-komatta\.jp$/m0

    移動を意味する m コマンドを使う。どこかの行を 先頭に移動したいときは m0 とする(mNと するとN行目の後ろにいく)。どの行を移動対象とするかの指定が 「g/yareyare-komatta\.jp$/」で、 gが「全ての」を意味し、 /yareyare-komatta\.jp$/ が 「yareyare-komatta.jpで終わる行」を意味する。 g を省略すると最初に見つかった行だけが移動する。

  2. pittashi-kankan.jp のドメインがなくなったので それらの人のアドレスを消したい。完全に消すのではなく 行の先頭に # マークを付けて無効化を意味するように 修正する。

    g/pittashi-kankan\.jp$/s/^/#/

    置換を意味するsコマンドは

    s/パターン/置換え語/

    のように指定する。パターンの部分に正規表現を 指定すると、それにマッチする部分が置換え語に置換される。 正規表現 ^ は行頭を意味するので、

    s/^/文字列/

    とすると、その行の先頭に 文字列 を追加する。

  3. カーソルのある行から最後まではあまり使わないので 行頭に # をつけたい。

    .,$s/^/#/

    ex(vi)では、範囲指定のときのピリオドは現在行を、$ は最終行を意味する。普通の数字はその行を意味する。たとえば、 「1行目〜10行目」なら範囲指定部分は、1,10 とする。 また、行の指定には足し算引き算も使えるので

    「現在行の2行下から、最終行の3行手前まで」

    は、

    .+2,$-3

    のように指定できる。

よく使うexコマンド

コマンドはたらき
:e!修正を破棄してファイルを読み直す。
:e ファイルファイル を新規に開く。
:e! ファイル 修正を破棄してファイル を新規に開く。
:r ファイル ファイル の内容を次の行に取り込む。
:r! コマンド コマンド を実行した結果を次の行に取り込む。
:範囲!コマンド 範囲コマンド の入力として実行し、 その結果と置き換える。
:範囲s/パターン/置き換え語/ 範囲に対し正規表現置換をする。パターンの区切り文字は /でなくても構わない。
:nコマンドラインで指定した 次のファイルへ。
:prevコマンドラインで指定した 前のファイルへ。
:rewコマンドラインで指定した 最初のファイルへ。

システム管理作業とvi

一括編集操作

前述したとおり、各種サーバプログラムの設定ファイルはテキストファイル である。設定は一発でうまく行くことはまれで、設定ファイルを何度も書き換え て試すことが多い。一度試しに書いてみた部分を消すときは、本当に消すのでは なくコメントアウトして一時的に無効化する。コメントアウトする部分は 1行だけでなく10行以上になることもあるのでカーソル移動を手で行なって 文字挿入していたらとても時間がかかる。viのexコマンドを使い、 指定した範囲やパターンにマッチする行を一括操作することで、1行でも 1000行でも同じ時間で編集できることが重要な意味を持つ。

ゴミを散らかさない

viはデフォルトでバックアップファイルを作らない(特別に進化した一部のvi 互換エディタを除く)。バックアップファイルは、一回前にセーブした内容を持っ ているというだけなので、それが正しい設定のものである保証はなく、実際には 役に立つことがほとんどない。バックアップファイルは人間が意識して正しいバー ジョンのものを残してこそ意味がある。

またバックアップファイルを作る設定だと、同じ大きさのファイルを別に作るこ とになるのでHDDの容量不足のときには書き込みエラーになることもある。もちろ んバックアップファイルがたくさん作られたら、それだけでディスクの無駄にな る。また、HDDの一部が故障して書き込み不能に陥っているようなときは、 現在正常に書ける領域にあるファイルを、別のHDD領域に移動してしまう ことになり、書き込みエラーを誘発する(※)。

Emacsなどはデフォルトでバックアップファイルを作るのでカスタマイズし ていない状態のrootユーザで設定ファイルを編集するとあちこちにバックアップ ファイルをばらまくことになり見苦しく、予期せぬトラブルを招くことになる。

(※) Log Structure Filesystem などでは全ての書き込みが未使用領域に 新規に書かれるためバックアップファイルを作るかどうかの影響は無関係である。

環境非依存性

サーバ管理をするようになると経験値が上がるので、色々なシステムを 使えるようになる。そのようなときに、あるOSにしかないテキストエディタで 管理することに慣れていると、別のOSで役に立たない。

viはUnix系システムのほぼ全てに標準装備されているので、 一度覚えておけば、どこに行っても困らない。さらには、バージョンアップで 使い方が変わったりしないので、10年〜20年後にも困らない。


目次


(C)2006 HIROSE Lab. koeki-u.ac.jp