管理者の第一歩、viのススメ

第5回 管理者の第一歩、viのススメ

エディタは世の中に星の数ほどあり、優劣はつけ難い。自分が一番使いやすいもの、慣れているものを使えばそれでよい。が、まさかのときに備えて最低限マスターすべきエディタもある。その筆頭がviだ。

なぜviなのか?

基本はvi

 UNIXにおけるエディタの2大潮流は、viとEmacsです。最近は、X Window System(以下X)を前提としたGNOMEやKDEに含まれるGUIベースのエディタも一般的になりつつあります。これらはWindows用のエディタと使い方が似ているのですが、Xの使えない環境では利用できません。

 Emacsは現代的なフルスクリーンエディタです。文字を打てば素直に反映されますし、X環境に対応したXEmacsもあります。かつてはワークステーションでも持て余すほど巨大なプログラムの代表でしたが、最近のPCではEmacsといえどもちっとも鈍重には感じません。いずれにしてもエディタには一長一短があり、簡単に優劣をつけられません。普段は自分の気に入ったもの、使いやすいものを使用すれば問題ありません。

 が、非常時にはそうもいきません。システムクラッシュの回復時に使うべきエディタとして考えると、Emacsは複雑すぎます。また、サーバマシンなどではEmacsがインストールされていない可能性もあります。しかし、viがインストールされていないマシンはまずありません。例えばRed Hat Linux 7.1では、Emacsが/usr/binにあるのに対して、viは/binにあります。つまり、viは最低限必要なコマンドに位置付けられているわけです。

viの特徴

 それでは、viの特徴を見てみましょう。何といっても、「モード」を持っていることが最大の特徴です。キー入力そのままに文字を入力する状態を「編集モード」、キー入力でviの機能を利用する状態を「コマンドモード」と呼びます。viの起動直後はコマンドモードであり、文字をタイプしてもその文字が入力されるわけではありません。文字を入力するには、[i](insert)や[a](append)などのコマンドを表すキーをタイプして編集モードに移行する必要があります。入力が終わったら、[ESC]キーを押してコマンドモードに戻ります。viを使うためには、どちらのモードになっているかを常に意識している必要があるということです(画面1)。

画面1 viの画面。最下部に「INSERT」と表示されており、編集モードであることが分かる

 2番目の特徴は、ラインエディタをベースとしていることです。ラインエディタといってもピンとこないでしょう。Windowsでは、edlinというラインエディタが用意されています。MS-DOS 3.1にはすでにあった由緒正しいエディタですが、使ったことのある人はほとんどいないと思います。

 viやEmacsはフルスクリーンエディタで、常にテキストが画面上に表示されています。これに対して、ラインエディタはコマンドを駆使してテキストを表示・編集します。viの第1の特徴は、実はラインエディタをベースとしているという第2の特徴から必然的に導かれるといっていいでしょう。

 ラインエディタは、コマンドを知らないと使えませんし、慣れないと極めて使いにくいものです。しかし、大きな長所があります。それは、とにかく文字の入出力ができれば使えることです。もう少し詳しく説明すると、viやEmacsといったフルスクリーンエディタでは、画面を縦横に使った表示をするだけに、そのためのコントロールシーケンスを必要とします。例えば、画面の上から5行目だけを書き換えるといったことができなければなりません。もちろん、Xやコンソールから使っていれば当然利用できる機能です。が、時としてシステムの調子がおかしくなったのをメンテナンスするとき、このコントロールシーケンスが働かなくなることがあります。また、シリアルラインからダム端末経由でログインしたときも、フルスクリーンエディタは使えないと思った方がいいでしょう。こうした場合でも、ラインエディタなら問題なく使えます。

 viの使い方、特にexモードの使い方を覚えておくと、いざというときに「ex」というラインエディタが使えて助かることがあるのです。システム管理者を志すなら、こうした事態にも備えておく必要があるでしょう。

 ちなみに、exはviのベースになったラインエディタの名前です。現在のLinuxディストリビューションでは、exもviも同一のファイルで、ハードリンクを使って別の名前のファイルとして用意されています。起動したときの名前に応じて、exとして動作するかviとして動作するかが決まるようになっています。

viの操作を覚えよう

まずは起動と終了

 では、早速viを使ってみましょう。実際には、viにはさまざまなバリエーションがあります。「nvi」、「vim」あたりが代表的なもので、どれがインストールされているかはディストリビューションにもよりますし、インストールしたパッケージにもよります。が、いずれの場合でも、

$ vi

とすることで実行可能なはずです。特定のファイルを編集するなら、引数としてそのファイル名を与えます。

 viを終了するには、[Z][Z]とタイプします。これで、ファイルのセーブとviの終了の両方が行われます。もし、「ZZ」という文字が入力されてしまったら、[Backspace]キーを2回押して文字を削除した後、[ESC]キーを押してからもう1度[Z][Z]とタイプしてください。ファイルをセーブせずに終了するなら、[:][q][!][Enter]です(編注)。

編注:以下、連続したキー入力は「[]」でキーを区切らずに表記する。例えば、[:][q][!]と入力する場合は:q!となる。[Enter]キーは省略。

入力とカーソル移動

 viが起動したら、まずは[i]キーを押して(viでは大文字・小文字を区別)でテキスト挿入モードにします。とりあえずはアルファベットだけを入力してみましょう(画面2)。

画面2

コマンド
機能
i カーソルのある場所に挿入
a カーソルの後ろに挿入
I 行頭に挿入
A 行末に挿入
o カーソルの下の行に挿入
O カーソルの上の行に挿入
表 編集モードに移行するコマンド

 入力が終わったら、[ESC]キーを押してコマンドモードにします。iはカーソルのある場所にテキストを挿入するコマンドです。似たようなものに、カーソルの後ろに挿入するa、行頭に挿入するI、行末に挿入するAがあります。さらに、カーソルのあるすぐ下の行に挿入するo、上の行に挿入するOも使えます。

 カーソルを動かすには何通りかの方法がありますが、基本は1文字ずつ動かす[h][j][k][l]です。[h]で左、[l]で右、[k]で上、[j]で下にカーソルが移動します。

 
k
h
l
j
図 文字単位の移動

 単語単位では、wbを使います。wで次の単語の先頭、bで1つ前の単語の先頭に移動します。行頭には数字の0、行末には$で移動できます。

 
コマンド
機能
  w 次の単語の先頭
  b 前の単語の先頭
  0 行頭
  $ 行末
  表 行内の移動

 10行先に移動したいときは、[j]キーを10回押してもいいのですが、10jとタイプしてもOKです。100行先に移動するなら100jですね。[j]キーを100回押すよりもずっと楽です。また、100行目に移動するなら100Gとタイプします。Gでファイル末なのですが、なぜかファイルの先頭に飛ぶコマンドがありません。これは1Gで代用できるからでしょうか。

 
コマンド
機能
  1G ファイルの先頭
  nG ファイルのn行目
  G ファイル末
  表 Gコマンドの使い方(nは数字)

削除

コマンド
機能
x カーソル上の文字を削除
X カーソルの前の文字を削除
dw 単語を削除
d^ 行頭まで削除
d$ 行末まで削除
dd 現在行を削除
df 指定文字までを削除
表 削除機能の一部

 人間にタイプミスはつきものですから、間違えた部分を削除できないと困ります。viでは、xでカーソルのある1文字を削除します。dwで単語の削除、d$で行末までの削除になります。

 もう1つ、dfとするとカーソルのある場所から、次に入力した文字までが削除されます。画面2を例に取ると、1行目の行頭にカーソルがあるときにdfiとタイプすると、thiが削除されます(画面3)。dfiの代わりにdfsとすると、thisの削除になります。


画面3

 1行丸ごと削除するときはddとタイプします。数字を先にタイプしてからddとすると、複数行を一気に削除できます。

 削除した文字はバッファ(Windowsのクリップボードに近いもの)に保存されており、pとタイプするとカーソルの後に、Pとタイプするとカーソルの前に挿入(プット)されます。ddpとすると、カーソルのある行とその1つ下の行が入れ替わります。

 
コマンド
機能
  p カーソルの後に最新のバッファ内容を挿入
  P カーソルの前に最新のバッファ内容を挿入
  表 プット(Windowsのペースト)機能

書き換え

 削除してから挿入すればどんな間違いでも修正できます。しかし、もう少しスマートな方法もあります。

コマンド
機能
r 1文字書き換え
R [ESC]キーを押すまで書き換え
cw 単語の書き換え
cf 指定文字までを書き換え
u アンドゥ機能
表 修正機能

 まず、1文字の書き換えを行うrコマンドで、これはカーソルのある文字に対して働きます。大文字のRコマンドだと、[ESC]キーを押すまで順に文字を書き換えられます。sを使うと、1文字削除した後に複数の文字を挿入できます。

 使いやすいのはcwcfでしょう。cwは単語の書き換えで、カーソルのある文字から次の単語の先頭になる文字の1つ前の文字までを書き換えます。入力する文字も複数で、入力が終わったら[ESC]キーを押します。

 cfは、dfに似ています。カーソルのある文字から次にタイプした文字までの文字列を書き換えます。これも複数の文字を入力できるので、入力が終わったら[ESC]キーを押して知らせます。

 間違いを正す手段として、uもあります。これは直前に行った作業をキャンセルして、元に戻してくれます。いわゆるアンドゥ機能ですね。

検索

 viでは、もちろん文字列の検索も可能です。[/]キーをタイプすると、画面の最下部に「/」で始まる行が現れます。ここで探したい単語を入力して[Enter]キーを押します。これで、カーソルのある場所からファイルの終わりに向かって検索を開始し、最初に見つかった文字列で停止します。

 逆に、カーソルのある位置からファイルの先頭に向かって検索するときは、[?]キーを押します。同じように画面最下部に「?」で始まる行が現れるので、そこに検索対象の単語を入力してから[Enter]キーを押します。

 
コマンド
機能
  / カーソル位置からファイル末尾に向かって検索
  ? カーソル位置からファイル先頭に向かって検索
  表 検索機能

 いずれの場合も、同じ文字列を続けて検索するときはnを押します。すると、次に見つかった文字列で停止します。

置換

 このあたりから、ラインエディタのコマンドに近くなってきます。

 カーソルのある行だけで置換を行うには、:s/文字列/文字列/を使います。

:s/original/replace/

とすると、最初に見つかった「original」という文字列が「replace」に置き換わります。これだと最初の1つしか置換できません。全部を置換するには、

:s/original/replace/g

と、後ろに「g」を付けます。

 また、viの置換は基本的に問答無用で実行されます。置き換えるかどうかをいちいち確認する場合には、

:s/original/replace/c

と、最後に「c」を付けます。もちろん、gと一緒に指定することもできます。

 1行目から10行目までで置換を行う場合は、

:1,10s/original/replace/

とします。では、ファイル全体で置換を行う場合はどうすればいいのでしょうか? この場合は、

:1,$s/original/replace/

あるいは

:%s/original/replace/

のようにします。「$」は最後の行を表します。ですから、$-10,$と指定すると最後の10行ということになります。%は1,$の別表記です。

 さて、置換対象の文字列中に「/」が入っている場合はどのように指定すればいいのでしょうか。この場合は2つの方法があります。1つは、「\」を前置してエスケープする方法です。/の数が少ないならこれでOKですね。/がたくさん出てくる場合は、文字列を区切る文字を適当に変更します。対象となる文字列に含まれない文字、例えば「:」などを使います。具体的には、

:s:tmp/new:tmp/old:

などとします。「/」が2回出てきますが、これまでのような区切り文字ではなく、置換対象文字列に含まれていることに注意してください。

 ここでは置換の基本的なことだけを紹介しましたが、「正規表現」を用いると複雑な指定も柔軟にできるようになります。正規表現については、次回にあらためて詳しく紹介する予定です。

ファイルの扱い

 UNIXが落ちることはまずないのですが、アプリケーションが止まることはままあります。ネットワークが途絶することもあるでしょう。こまめなセーブを習慣づけておくに越したことはありません。

 作成途中のファイルを保存するには、:wを使います。別の名前でセーブするなら、:w filenameです。

 一方、ファイルを読み込むのは:r filenameです。これを行うと、カーソルのある次の行に挿入されます。

コマンド
機能
:w ファイルの保存
:r ファイルの読み込み
:e 別ファイルの編集
:! 指定コマンドの実行
表 ファイル操作とコマンド実行。コマンドに「!」を付けると強制実行になる

 ほかのファイルを編集するときは、:e filenameです。既存のファイルであればそれが読み込まれ、存在しないファイルであれば新しく作成されます。現在編集中のファイルがセーブされていない場合は、:eで新しいファイルの編集を指定しても実行できません。:wでセーブするか、:e! filenameで現ファイルをセーブせずに新しいファイルを編集するか、いずれかを選択する必要があります。

 残念ながら、Emacsとは違ってファイル名の補完が使えないので、正確なファイル名をタイプする必要があります。覚えていないなら、:!lsとしてファイルの一覧を表示しましょう。あるいは^Z([Ctrl]+[Z]キー)で一時中断してシェルに戻り、ファイル名を確認したところでfgコマンドを使って再実行する手もあります。

 今回は、viの基本的なコマンドについて簡単に紹介しました。viにはほかにも多くのコマンドがあるほか、いくつか例を示したようにコマンドを組み合わせることで一味違った効果を発揮したりします。皆さんもいろいろ試してみてください。