Vi入門


viはUNIXで、標準に付いてくるスクリーン(?)エディタです。ラインエディタがVisualになったからviです。お客さんが、Emacsなどのインストールを許さない事もありますので、標準で使えるviを覚えておきましょう。

【記述上の注意】
は、任意の数字を意味します。アルファベットのnとの区別のために下線を入れています。
「改行」はEnterキーです。
特に断りのない場合、[]で囲った文字は省略可能です。

  1. 起動と保存と終了 とりあえず、起動の仕方と終了の仕方を覚えておきましょう。
    1. 起動
      >vi [ファイル名]「改行」
      >view ファイル名「改行」

      viewで起動するとリードオンリーで開きます(ファイルを更新できません。)。

    2. 保存と終了
      コマンド入力モードで下記のコマンドを実行します。コマンドは大文字と小文字を区別しますので、注意してください。
      • 終了
        :q「改行」
        これだと、ファイルを修正していると終了を拒否されます。
      • 保存しないで終了
        :q!「改行」
      • 書き込んで終了
        :x「改行」   または   ZZ
      • 保存して終了
        :wq [ファイル名]「改行」

        ファイル名を指定すると名前を変えて、指定しなければ上書き保存します。

      • 保存
        :w [ファイル名]「改行」
      • 追加保存
        :w >>[ファイル名]「改行」

        指定されたファイルの末尾に追加します。

  2. モード
    さて、保存と終了のところでコマンド入力モードと言う言葉が出てきました。
    viにはテキスト入力モードとコマンド入力モードと言う2つのモードがあります。 ウィンドウズのエディタで、メニューにある機能とカーソルを移動したりスクロールしたりする機能はコマンド入力モードで、それ以外のエディットボックスで行うテキストの編集はテキスト入力モードで行います。
    先ほどの終了のコマンドはコマンド入力モードで入力します。編集モードで打ってもそのままファイルが編集されるだけです。
    コマンド 機能
    i 現在のカーソル位置の文字の前に文字を挿入するテキスト入力モードへ
    I 行の先頭に文字を挿入するテキスト入力モードへ
    a 現在のカーソル位置の文字の後に文字を追加するテキスト入力モードへ
    A 行末に文字を挿入するテキスト入力モードへ
    o 現在の行の後に1行追加してテキスト入力モードへ
    O 現在の行の前に1行追加してテキスト入力モードへ
    R 上書きのテキスト入力モードへ
    ESCキー コマンド入力モードへ復帰

    ところで、現在のモードを表示することが出来ます。便利なので覚えておきましょう。

    :set verbose showmode「改行」

    このコマンドがエラーになる場合は、

    :set showmode「改行」

    として見てください。
    画面の右下にモードが表示されるようになります。

  3. 移動
    カーソルの移動やスクロールは、コマンド入力モードのコマンドによって行います。
    1. カーソルの移動
      ターミナルの設定によっては、カーソルキーやスペースキー、バックスペースキーで移動できますが、これが使えない場合もありますので、覚えておきましょう。
      移動のキーのアサインはキーボードと配列と一致しています。右手のホームポジションのあたりを見てください。
      h j k l

      hが左、jが下、kが上、lが右となっています。

      ところで、10行上に移動したいときはどうするかというと、10kとします。viでは、コマンドの前に数字を指定することが出来るものが結構あります。

      Ctrl+Pなどもありますが、混乱の元になると思いますので、ここでは説明しません。興味のある方は自分で調べて見てください。

    2. 行内の移動
      コマンド 機能
      0 行頭
      ^ 行頭(行頭に空白がある場合は、空白のあと)
      $ 行末
      []| 行頭からn番目の文字に移動。nを省略すると行頭へ飛びます。|は縦棒です。
      b 一つ前の単語(:;を1つの単語として扱う)
      B 一つ前の単語
      w 次の単語(:;を1つの単語として扱う)
      W 次の単語
      e 単語末尾(.,を単語の区切りとして扱う)
      E 単語末尾
      E 単語末尾
      f検索文字 検索文字を行頭から検索して移動
      F検索文字 検索文字を行末から検索して移動
      t検索文字 検索文字を行頭から検索してその文字の1つ前に移動
      T検索文字 検索文字を行末から検索してその文字の1つ前に移動
    3. 大きな移動
      コマンド 機能
      H 画面内の最初の行
      M 画面内の中央の行
      L 画面内の最終行
      G ファイルの最終行
      G n番目の行
      Ctrl+f 1画面分下
      Ctrl+b 1画面分上
      Ctrl+D :set scroll=で設定された分下
      Ctrl+U :set scroll=で設定された分上
    4. 便利な移動
      コマンド 機能
      % (または)の上で押すと対になった括弧へ飛びます。
  4. 編集
    1. 削除(Delete)
      コマンド 機能
      []x n文字削除。n省略時は1文字。
      D カーソルのある文字以降行末まで削除
      []dd n行削除。n省略時は1行。
      dh カーソルのある文字を含んで前へn文字削除
      dl カーソルのある文字を含んで後ろへn文字削除
      dG カーソルのある行からファイルの先頭からn番目の行までを削除
      dG カーソルのある行から最終行までを削除
      :[n1[,n2]]d「改行」 n1行からn2行(n2には最終行を意味する$を指定できます。)までを削除します。
      n1、n2を指定しなかった場合はカレント行の削除です。
      :[g|v]/正規表現/d「改行」 カレント行の次の行以降で正規表現に一致した最初の行を削除。
      gを付けると一致する行が全て削除されます。
      vを付けると一致しない行が全て削除されます。
      (正規表現についてはあとで説明します。)
      :[/正規表現1/,/正規表現2/]d「改行」 カレント行の次の行以降で正規表現1に一致した行から、
      カレント行の次の行以降で正規表現2に一致した行までを削除。
      (正規表現についてはあとで説明します。)

      d+移動コマンドでいろいろな削除が出来ます。

    2. コピー(Yank)&ペースト(Paste)
      コマンド 機能
      yl カーソルのある文字を含んで後ろにn文字をコピー
      yh カーソルのある文字を含んで前にn文字コピー
      []yy n行コピー
      []Y n行コピー
      p ペースト

      y+移動コマンドでいろいろなコピーが出来ます。

    3. カット&ペースト

      「d」「x」「D」などの削除コマンドを実行後に「p」を行うとカット&ペーストとなります。
      【注意】:で始まる削除コマンドでは、バッファにコピーされないためペーストできません。

    4. 行のコピーと移動
      コマンド 機能
      :[n1[,n2]] co n3「改行」 n1行からn2行(n2には最終行を意味する$を指定できます。)までをn3行の後ろにコピーします。
      n1、n2を指定しなかった場合はカレント行のコピーです。coの前後にはスペースを入れてください。
      n3に0を指定するとファイルの先頭にコピーできます。
      :[n1[,n2]] m n3「改行」 n1行からn2行(n2には最終行を意味する$を指定できます。)までをn3行の後ろに移動します。
      n1、n2を指定しなかった場合はカレント行の移動です。mの前後にはスペースを入れてください。
      n3に0を指定するとファイルの先頭に移動できます。
  5. 検索
    コマンド 機能
    /検索文字列「改行」 検索文字列を前方検索
    ?検索文字列「改行」 検索文字列を後方検索
    n 検索時と同一方向の次検索
    N 検索時と逆方向の次検索
  6. 置換(Change,Replace)

    いわゆる置換とは、ちょっと違います。指定した範囲の上書きモードと言ったらいいのでしょうか。

    コマンド 機能
    c+移動コマンド d+移動コマンドやy+移動コマンドと同様に範囲の指定ができます。このあと置換える文字を入力していきます。
    []cc n行置換。n行削除されて1行追加されるイメージです。n省略時は1行。
    []s n文字置換。1省略時は1文字。
    []S n行置換。n省略時は1行。ccと同じです。
    []r置換後の文字 n文字を置換後の文字で置換えます。3rAとやると3文字がAになります。

    モードの時に出てきたRコマンドの方が使いやすいと思います。

  7. その他
    1. 繰り返し
      コマンド 機能
      .(ドット) 同じコマンドを繰り返します。
    2. タブ
      コマンド 機能
      []>> n行の行頭にタブを追加します。

      タブの幅は、

      :set tabstop=「改行」

      で指定できます。

    3. アンドゥ
      コマンド 機能
      u アンドゥ
    4. 行の連結
      コマンド 機能
      []J カーソルのある行と次の行を連結します。
      nを指定するとn行連結されます。ただし、指定しない、1、2は同じ結果になります。
    5. UNIXのコマンドの実行
      コマンド 機能
      :!UNIXのコマンド「改行」 UNIXのコマンドを実行します。
    6. 読み込み
      コマンド 機能
      :[]r ファイル名「改行」 n行目の後ろにファイルを読み込みます。
      nを省略するとカーソルのある行の次の行に読み込まれます。
      また、0を指定すると先頭に読み込まれます。
      :[]r!UNIXのコマンド「改行」 UNIXコマンドの結果を読み込みます。
    7. 大文字←→小文字
      コマンド 機能
      []~ 大文字小文字の変換を行います。
    8. 行番号の表示
      コマンド 機能
      :set number「改行」 行番号を表示。
      :set nu「改行」 行番号を表示。
      :set nonumber「改行」 行番号を非表示。
      :set nonu「改行」 行番号を非表示。
  8. 正規表現を用いた置換

    UNIXの多くのコマンドが正規表現を用いることが出来るようにviでも正規表現が使えます。
    なお、検索でも正規表現を使用できます。

    :[範囲] s/正規表現/置換後の文字列/[g][c]

    コマンドは、このような形になります。
    「範囲」で指定された行で、「正規表現」と一致する部分を「置換後の文字列」に置き換えると言うコマンドになります。
    末尾のgは、1つの行内に正規表現に一致するものが複数あった場合、gをつけないと1つだけが置き換わりますが、gをつけると全てのマッチするものが置換されます。
    末尾のcは、インタラクティブに置換を確認する場合につけます。yと答えたものだけ置換が行われます。

    1. 正規表現の指定の仕方

      範囲の指定でも正規表現が使えるため、先に正規表現を説明します。
      (正規表現は、言語やツールによって若干違います。気を付けてください。)

      \ それに続くメタ文字の特別な意味を失わせて、その文字自体の意味にする。
      .(ドット) 改行以外の任意の一文字
      * 直前の文字または正規表現の0回以上の繰り返し。
      [文字リスト] 文字リストに含まれる一文字。
      [ABCD]は、A、B、C、Dのどれかと一致すればよい。
      -を使用すると範囲指定できる。[A-D]は、[ABCD]と同じ。
      [^文字リスト] 文字リストに含まれない一文字。
      -を使用して範囲指定できる。
      ^ 正規表現の先頭で使われた場合は、行頭。
      $ 正規表現の末尾で使われた場合は、行末。
      \< 単語の先頭と一致。
      \> 単語の末尾と一致。
      \(\) \(と\)で囲んだ部分の正規表現に一致した文字列を記憶しておいて、置換後の文字列の\1,\2で参照する。
      範囲指定の時には、無意味です。

      例えば、Testを検索したい場合。/Test/

      行の先頭のTestは、/^Test/

      行末は、/Test$/

      のようになります。

    2. 範囲の指定の仕方
      指定 説明
      指定なし カレント行を意味します。
      番号 行の絶対位置指定です。
      :5は5行。
      複数の行の範囲を指定する場合は、:5,10のようにします。
      この場合は、5行目から10行目になります。
      .(ドット) カレント行を意味します。
      :.,10と言うようなことも出来ます。
      $ ファイルの最終行を意味します。
      :3,$は3行目から最終行までを意味します。
      % ファイルの全ての行を意味します。
      +番号 カレント行との相対位置を意味します。-も指定できます。
      :5,+4は、5行目からカレント行+4行目までを意味します。
      /正規表現/

      正規表現に一致した行を意味します。
      :1,/正規表現/や:/正規表現1/,/正規表現2/と言った指定もできます。

      :/正規表現/とした場合、カレント行の次の行から検索を始めて最初に一致した行のみを対象とします。

      一致する全ての行を対象としたい場合は、:g/正規表現/とします。

      :/正規表現1/,/正規表現2/はそれぞれ、それぞれカレント行の次の行から検索して
      正規表現1と一致する行から、正規表現2と一致する行までを対象とします。

      正規表現と不一致の行を対象としたい場合は:v/正規表現/とします。
      この場合は、gを指定したのと同様に、全ての行で不一致のものを対象とします。

    3. 置換後の文字列の指定の仕方

      例えば、全ての行のTESTをTestに変えたい場合、

      :%s/TEST/Test/

      となります。置換後の文字の指定には、それほどバリエーションはないのですが、下記のようなメタ文字があります。

      \ それに続くメタ文字の特別な意味を失わせて、その文字自体の意味にする。
      & 正規表現と一致した文字列
      \番号 正規表現の\(\)で囲まれた部分と一致した文字列を持ってくる。

      メタ文字の使い方ですが、
      例えば、2文字以上連続した英大文字を括弧で囲みたい場合
      :%s/[A-Z][A-Z][A-Z]*/(&)/
      のようにします。

  9. カスタマイズ

    ここまでで、:set コマンドをいくつか照会してきましたが、 setで設定しても、viを立ち上げ直すともとに戻ってしまいます。 これをvi起動時から有効にするには、2つの方法があります。

    1. .exrc

      ホームディレクトリのファイル「.exrc」を開いて、setコマンドを書いて保存します。先頭の:はいりません。

      set nu
      set tabstop=4

      一行に書いてもかまいません。

      set nu tabstop=4

    2. 環境変数EXINIT

      kshなどBシェル系のシェルであれば、ホームディレクトリの「.login」に

      EXINIT='set nu tabstop=4'
      export EXINIT

      を追加します。
      Cシェル系であれば。「.login」か「.cshrc」に

      setenv EXINIT 'set nu tabstop=4'

      を追加します。

    viの機能を紹介してきました。これ以外にも機能がありますので、自分で研究してみてください。