1. 概要

デジタル時代に物事を成し遂げることは、テキストデータをどれだけ速くそして効果的に扱うことができるかに大きく依存しています。

このチュートリアルでは、従来のviエディターを、テキスト編集用の最小限でありながら強力なツールとして学習するための昔ながらのアプローチを採用します。

2. 従来のvi

探索の範囲を従来のviエディター制限します。 そのことを念頭に置いて、viとexラインエディタとの関係を理解することから始めましょう。

2.1. 設定

長い間、viの機能セットは Single Unix Specification の一部であり、ほとんどのLinuxディストリビューションのデフォルトのエディターになっています。 ただし、現在、ほとんどのオペレーティングシステムは、 Vim(Vi IMproved)としてクローンを介してviサポートを提供しています。

ls -l $(which vi)
lrwxr-xr-x  1 root  wheel  3 Jan  9 05:03 /usr/bin/vi -> vim

したがって、 vi を呼び出すときはいつでも、実際にはvimを呼び出しています。

viで動作するすべてのものがVimで引き続き動作することを保証するために、 Vimの互換モード(-C)を使用するオプションがあります。

$ vim -C

しかし、拡張クローンとして、Vimは当然、従来のviエディターよりも幅広い機能セットを提供します。 また、互換モードでは、Vim内で相互に排他的な機能を使用することを制限しません。

さて、機能的な観点からは、それはすべて公平で問題ありません。 ただし、最終的に非vi機能を使用して、それがvi機能であると想定する場合があります。

このような混乱を避け、viエディターでサポートされる機能を明確にするために、viがプリインストールされたすぐに使用できる仮想Docker環境を活用します。

それでは、仮想環境を実行して、物事を進めましょう。

$ docker run -it tapankavasthi/vi
root@0bf072c119aa:/tmp/vi/work#

2.2. viexです

仮想コンテナ内で、fileコマンドを使用してvi実行可能バイナリファイルを調べてみましょう。

# file $(which vi)
/usr/local/bin/vi: symbolic link to ex

ご覧のとおり、vi実行可能ファイルはexbinaryファイルへのシンボリックリンクです。 したがって、viを強化する基盤となるプログラムがexであることは明らかです。

2.3. exモード

サンプルのhello.txtファイルを作成し、exコマンドを使用して開きます。

# printf "Line-1\nLine-2\n" > list.txt
# /usr/local/bin/ex list.txt

驚いたことに、ファイルを開くと、ファイルの内容が表示されません。 一方、コロン()コマンドプロンプトが表示されます。

"hello.txt" 2 lines, 14 characters
:

そのため、これはexのデフォルトモードであり、コロンプロンプトexコマンドを実行することが期待されています。 それでは、記号が前に付いた p (印刷)コマンドを試してみましょう。

"hello.txt" 1 line, 14 characters
:%p
Line-1
Line-2
:

2.4. exのビジュアルモード

ex のコマンドラインの使用法を見ると、 -v (ビジュアル)オプションを見つけることができます。

Usage: ex [- | -s] [-l] [-L] [-R] [-r [file]] [-t tag]
       [-v] [-V] [-w size] [+cmd | -c cmd] file...

q (quit)コマンドで最後に開いたファイルを終了し、-vオプションで再度開きます。

$ /usr/local/bin/ex -v list.txt

興味深いことに、ファイルが開かれるとすぐにファイルの内容を確認できるようになりました。 まあ、それは正しくビジュアルモードと呼ばれています:

Line-1
Line-2
~
~
~
"list.txt" 2 lines, 14 characters

または、viコマンドを使用して、exのビジュアルモードを呼び出すことができます。

$ vi list.txt

したがって、viはex-vであると言えます。

3. モーダルエディタとしてのvi

viコマンドを使用してファイルを開くと、exのビジュアルモードに入ります。 しかし、viの観点からは、これがデフォルトのモードです。

このモードでexコマンドのサブセットを使用して、編集を行うことができます。 そう、 これは一般にコマンドモードとして知られています。 viは、 ほとんどのキーストロークがテキストの入力に変換される挿入モードファイルに。

また、 Esc を押すか、 i と入力することで、コマンドモードと挿入モードを簡単に切り替えることができます。

最後に、viは、視覚的なコンテキストを失うことなく、コロンプロンプトでコマンドを入力できるex-likeモードへの簡単なアクセスも提供します。

さて、これらのモードを切り替えることになると、視覚的なアプローチをとることによってこれを理解するのが最善です:

簡単な演習として、この循環フローを使用して、exのコロンプロンプトから挿入モードに移行する方法を理解しましょう。

4. ビジュアルモードの言語

各モードで、viは特定の一連の命令を理解します。 ビジュアルモードで効果的に機能するために、その言語の概念を学ぶことから始めましょう。

4.1. 文法の基本

一般的に、viに特定の順序で編集命令を提供する必要があります。

[Modifier][Operator][Operand]

明確にするために、3文字を削除する簡単な手順を見てみましょう。

そのため、文字、単語、および行の形式のテキストオブジェクトがオペランドとして機能します。 一方、オペレータは、 change c )、 delete d )、copy[などのテキスト処理を実行します。 X129X]( y )、 replace r )など。 そして最後に、数値カウントなどの修飾子は、オペレーターの元の動作を変更できます。

基本的に、テキスト編集は、問題に対する複数の解決策を得ることができる数式を解くことに非常に似ています。 ただし、この場合は、最小限のキーストロークで実行するように努める必要があります。 そして、それがviでの作業中にシングルキーストロークが非常に一般的である理由の1つです。

4.2. 一般的なオペランド

テキストを扱っているので、viはオペランドの3つの広いカテゴリを理解します。 つまり、文字、単語、および行。

だから、簡単に聞こえますか? しかし、悪魔は詳細に眠ります、 特に言葉の概念のために。

キャラクターの概念を理解することから始めましょう。 文字オペランドは、カーソルの現在の位置や行の先頭などの参照ポイントを使用して識別されます。

  • 現在の行の場合、0および$は開始と終了を示します
  • カーソル位置は、hlがそれぞれ左右の文字を表します。
  • ^_は、どちらも最初の非空白文字を識別します
  • N | は、 N th 列の文字を示し、Nの欠落値は1として解釈されます。 ]

それでは、単語に使用されるviの定義を詳しく説明しましょう。

  • その中の最初のものは語彙 W )であり、空白以外の文字の連続したシーケンスであり、常にスペースのブロックが続きます [^ I] * または行末文字( $
  • そして、2番目は論理単語(w)で、これは常に非空白文字で始まり、その後に [a-zA-Z0-9]*のシーケンスが続きます。

さらに、単語のオペランドから派生したいくつかの文字識別子について学びましょう。

 

最後に、いくつかの行固有のオペランドも見てみましょう。

4.3. 一般的な演算子

オペランドは関連する文字の明確な位置IDを保持するため、カーソル移動は、演算子を明示的に指定しない場合を適用するデフォルトの演算子です。 したがって、コマンドモードのときに、オペランドに対応するキーを押すと、オペランドで識別される位置にカーソルが移動します。

ただし、テキストが誤って変更されるのを防ぐために、意図を明示的に表現する必要のある演算子が他にもいくつかあります。 それらのいくつかを見てみましょう:

もちろん、オペレーターのリストは最初は私たちを圧倒する可能性があります。 しかし、文法構造の強力な基盤により、これらは直感的に覚えることができます。 それらが実際に動作するのを見る準備をしましょう。

[IE9の場合]> <![endif] ビデオプレーヤー

メディアエラー:フォーマットがサポートされていないか、ソースが見つかりません

ファイルのダウンロード:https://www.baeldung.com/wp-content/uploads/sites/2/2020/05/demo-v2.mp4?_ = 1

00:00
00:00
00:00

ここまでは順調ですね。 ここで、挿入モードになっているように感じる2つの演算子を見てみましょう。

次に、 c (演算子)と w (オペランド)の組み合わせを使用して単語を変更する方法を見てみましょう。

ビデオプレーヤー

メディアエラー:フォーマットがサポートされていないか、ソースが見つかりません

ファイルのダウンロード:https://www.baeldung.com/wp-content/uploads/sites/2/2020/05/vi-cw.mp4?_ = 2

00:00
00:00
00:00

スコープバージョンの挿入モードに移行することがわかります。ここで、$記号は、置換テキストの意図されたソフト境界を示します。そして、変更を確認して通常のビジュアルモードに戻るために、 Escキーを押します。

4.4. 運用範囲

などの編集操作用 dw d/ など、文字ごとに左から右にトラバースしています。 したがって、操作の範囲は文字レベルです。

ただし、dj、ck、yjなどの操作の編集に関しては、ラインレベルで操作しています。

このような場合、現在のカーソル位置とjまたはkの対象となる文字位置の間にあるテキストは2行にまたがっています。 したがって、これらの操作の場合、の結果は、2行の削除、変更、またはコピーです

ビデオプレーヤー

 

4.5. 繰り返し

多くの場合、テキスト編集には、同じ操作を複数の文字、単語、または行に適用するなどの反復作業が含まれます。 また、viを使用すると、次の2つのサービスを簡単に利用できます。

  • ドット(。)演算子は最後の編集操作を再実行します
  • コマンドの前の数値修飾子は、後続の多くのオペランドに対してそれを繰り返します

適切なタブインデントが必要なコードがあるとしましょう。 もちろん、 >> << オペレーターはここで重宝します。

したがって、1つのタブで複数の連続する行をインデントする必要がある場合は、>>の前に数値数量詞を使用できます。

ビデオプレーヤー

 

ここで、同じ行に複数のタブインデントが必要な別のシナリオがあります。 だから、ここで使用できます >> また << 一度、続いてドット前のコマンド実行を繰り返す演算子:

ビデオプレーヤー

5. コンテキスト管理

ナビゲーションとコンテキスト管理を容易にするために、viはマーカーとレジスターを提供します。 それらを詳しく学びましょう。

5.1. マーカー

テキスト編集には、ある行から別の行への多くのカーソル移動が含まれます。 残念ながら、そうしている間、現在のコンテキストを見失う可能性があります。 したがって、この問題を解決するために、viでは後で使用できるように現在のカーソル位置をマークできます。

マーカーを使用するには、まず、マーカーに関連付けられている重要なキーバインディングについて理解しましょう。

  • mλはマーカーを作成します–ここで、λはaからzまでの任意の小文字です。
  • ‘λは、マークされた行から最初の非空白文字を識別します
  • `λは、マーキングが行われたライン上の正確な位置を識別します
  • ‘` は、カーソルの前の行の位置にある最初の非空白文字を識別します
  • `’は、カーソルの前の行の位置の正確な位置を識別します

詩の本文とその参照という2つのセクションを含むファイルがあるとします。 mpmrでマークを付けて、2つのセクション間を移動する方法を見てみましょう。

ビデオプレーヤー

メディアエラー:フォーマットがサポートされていないか、ソースが見つかりません

ファイルのダウンロード:https://www.baeldung.com/wp-content/uploads/sites/2/2020/05/vi-markers.mp4?_ = 6

00:00
00:00
00:00

これで、ある時点でファイル内の参照のリストが不要になった場合は、このマーカー情報を編集操作 G $ d’r:で利用できます。

ビデオプレーヤー

メディアエラー:フォーマットがサポートされていないか、ソースが見つかりません

ファイルのダウンロード:https://www.baeldung.com/wp-content/uploads/sites/2/2020/05/vi-marker-use.mp4?_ = 7

00:00
00:00
00:00

5.2. レジスター

ほとんどのテキスト編集環境では、クリップボードの概念があり、後で使用するために一部のコンテンツをコピーできます。 しかし、 viを使用すると、registersと呼ばれるそのようなプレースホルダーバケットが複数取得されます。

そのため、レジスタと変数を混同しないでください。 多くの場合、変数名はユーザー定義ですが、事前定義されたレジスタのセットがあり、名前を変更することはできません。 すべてのレジスタ名は、文字で始まり、その後に1文字が続きます。

当然、レジスタは、 yank(y) delete(d) cut(x)pasteなどのテキスト転送操作をサポートします。 (p)

<register-name><text-transfer-operator>

したがって、 “5yy 操作は、その行を番号レジスタ” 5 にコピーし、必要に応じて、“5pまたはのような操作を実行できます。 「5P

これは単純なユースケースでは問題なく機能しますが、番号レジスタ「0-9」のコンテンツを明示的にオーバーライドしないようにする必要があります。 これは、viが過去10回のテキスト転送操作からのテキストを保存する手段として数値レジスタを使用しているためです。

Text Transfer -> "0 -> "1 -> "2 -> "3 -> "4 -> "5 -> "6 -> "7 -> "8 -> "9 -> Lost

この一連のテキスト転送は、レジスタを明示的に使用した場合でも発生します。 したがって、数値レジスタに明示的に書き込んでいる場合、viがワークフローに干渉する可能性が常にあります。

さて、viレジスタのプールの中で、“azと”AZはnamed-registersと呼ばれます。 これらのレジスタについて注意すべき重要な点は、すべての小文字のnamed-registerとそれに対応する大文字のnamed-registerが同じストレージの場所を指していることです。 ただし、テキストを移動している間は、異なる動作を示します。

  • 小文字の名前付きレジスタ“ a–“ zは、古いコンテンツをそれらに移動された新しいコンテンツに置き換えます
  • 大文字のnamed-registers“ A –“ Zは、改行区切り文字を使用して、前のコンテンツに新しいコンテンツを追加します

ここで、HTTPとHTTPSのURIが混在するファイルで作業していると想像してみましょう。 そして私たちの目標はそれらを分離することです。 興味深いことに、viの delete 操作は、カット操作のように機能し、データをレジスタから保存および取得できます。 それでは、delete操作とレジスタを使用してユースケースを解決するための戦略をスケッチしましょう。

  • レジスタ“Sおよび“Uは、それぞれHTTPSおよびHTTPURIのリストに使用できます。
  • dd 操作を使用して、URI情報を一時的にレジスタに転送できます
  • レジスタ内の古いデータを消去するには、最初の削除で小文字のnamed-registerを使用できます。
  • マーカーsおよびuは、HTTPSおよびHTTPURIの分離リストのロケーションコンテキストをブックマークするために使用されます

最後に、実際の計画を見てみましょう。

ビデオプレーヤー

メディアエラー:フォーマットがサポートされていないか、ソースが見つかりません

ファイルのダウンロード:https://www.baeldung.com/wp-content/uploads/sites/2/2020/05/vi-registers.mp4?_ = 8

00:00
00:00
00:00

6. exモード

exはもともとラインエディタユーティリティだったので。 したがって、編集タスクに行レベルの操作が含まれる場合、exモードが非常に役立つことがわかります。 コロンプロンプトでいくつかのコマンドを実行する準備をしましょう。

6.1. アドレスの基本

exモードでは、特定のコマンドを実行する回線アドレスを指定する必要があります。 このため、exの編集コマンドのほとんどにはaddress_rangeプレフィックスが必要です。

:<address_range> <editing-command>

さらに、アドレス範囲をさまざまな形式で指定できます。

  • 数値の行番号、現在の行(。)、または最後の行($)の形式の絶対アドレス
  • 方向( + )として表される現在のラインに対する相対アドレス、およびラインステップをカウントするための正または負の数
  • 正規表現として/regex /
  • 上記の3つのタイプのいずれかの2つのアドレス値のコンマ区切り値
  • 全範囲の線として記号で表されます

アドレスを指定しない場合、デフォルトでは、操作は現在の行(。)に対してのみ実行されることに注意する必要があります。

アドレスの概念の理論的理解ができたので、 p print )コマンドを使用してこれを実際に見てみましょう。

ビデオプレーヤー

メディアエラー:フォーマットがサポートされていないか、ソースが見つかりません

ファイルのダウンロード:https://www.baeldung.com/wp-content/uploads/sites/2/2020/05/vi-ex-address.mp4?_ = 9

00:00
00:00
00:00

現在の行は、各アドレス評価の後に変更されることに注意する必要があります。 そのため、この動作は p print )コマンドなしで使用して、アドレス範囲の最後の行に移動できます。

:<address-range>

6.2. よく使う編集コマンド

p (コマンド)はアドレスの概念を理解しようとするときに便利ですが、複数行のビジュアル画面がある場合は実際には必要ありません。 それでは、exモードで頻繁に使用される編集コマンドを実際に体験するために時間をかけてみましょう。

まず、 delete d )、 move m )などの簡単なコマンドを見てみましょう。

  • [address_range] d [register] 、アドレス範囲からレジスタに行を移動するために使用できます
  • [address_range] y [register] 、アドレス範囲からレジスタへの行をヤンクするために使用できます
  • [address_range] pu [register] は、指定されたアドレス範囲の後にレジスタの内容を配置するために使用できます
  • [address_range] j は、指定されたアドレスに該当する行を結合するために使用できます
  • [address_range] m 、の後に一連の行を配置するために使用できます target_address
  • [address_range] co 、の後に行の範囲をコピーするために使用できます target_address

次に、substitution コマンド( s )を見てみましょう。これは、おそらく最も頻繁に使用されるexコマンドの1つです。

:[address_range] s/pattern/replacement/[[g|count][cp]]

名前が示すように、 sコマンドは、指定されたアドレス範囲のパターンを検索し、それを置換文字列に置き換えます。 デフォルトでは、行ごとに1つの置換のみが実行されますが、この動作を変更できます。

  • g global )フラグを使用すると、行ごとのすべての一致が置き換えられます
  • count 値は、1行あたりの置換数を制限します
  • c confirm )フラグは、置換を行う前に確認を求めるプロンプトを表示します
  • p print )フラグを使用すると、最後に置換が成功した行が印刷されます

ここで、ファイル内のアイテム名のリストが各行に1つずつあるとします。 そして、私たちの目標は、それを1行のコンマ区切りリストに変換することです置換(s)および結合(j)コマンドを使用してこれを行う方法を見てみましょう。

ビデオプレーヤー

 

キーは、 j がコマンドモードではカーソルを1行下に移動しますが、exモードでは結合するように、さまざまなモードでさまざまなアクションを実行できることに注意する必要があります。

6.3. 繰り返し

viを非常に強力にする機能の1つは、アクションを簡単に繰り返す機能です。 また、ex モードで編集操作を繰り返し実行するには、 g global )コマンドを使用できます。

:[address_range]g/pattern/cmd

デフォルトでは、ex-modeの編集コマンドは、アドレス範囲全体で1回実行されます。 ただし、をグローバル(g)コマンドと組み合わせて使用すると、パターンに一致するアドレス範囲の各行に対してコマンドが1回実行されます。

HTTPとHTTPSのURIの混合リストを分離する必要があったURI分離の問題を再検討しましょう。ただし、今回は、exモードで解決します。

ビデオプレーヤー

メディアエラー:フォーマットがサポートされていないか、ソースが見つかりません

ファイルのダウンロード:https://www.baeldung.com/wp-content/uploads/sites/2/2020/05/vi-ex-global.mp4?_ = 11

00:00
00:00
00:00

 

繰り返しコマンドのカテゴリのさらに別の宝石は、 & 指図それは私たちを可能にします最後の置換コマンドを繰り返します

それでは、これを使用して、「(」と「)」文字のみで構成される特定の式がバランスの取れた文字列の基準を満たしているかどうかを調べてみましょう。 バランスの取れた文字列の場合、すべての開き括弧の後に、対応する閉じ括弧が続きます。

これで、一致する括弧()の各ペアを空の文字列に繰り返し減らすことでこれを確認できます。 さらに、置換コマンドがパターンと一致しない場合は停止します。 そして、空の行が残っている場合、元の文字列はバランスが取れていました。

ビデオプレーヤー

 

6.4. バッファ管理

これまでに、ファイルに対してさまざまな編集操作を実行してきました。 変更が画面に表示されていることを確認しましたが、何を推測しますか? 変更がディスク上のファイルに永続的に反映されるわけではありません。 これは、バッファを使用していたためです 、実際にはファイルの内容のコピーと揮発性メモリに常駐 。 さらに言えば、偶数レジスタはバッファのカテゴリです。

変更をディスク上のファイルに永続的に書き込むには、 w(書き込み)またはw! (強制書き込み) コマンド:

:w[!] [filename]

現在開いているファイルとは異なるファイル名を指定することで、新しいファイルに変更を書き込むことができることに注意する必要があります。 そして、後で終了したい場合は、 q quit )または q!(書き込みなしで終了)コマンドを使用できます。 ただし、 viを終了するとすぐに、そのレジスタで使用可能なすべてのデータも失われます。

HTTPおよびHTTPSURIの分離リストを含むファイルを選択しましょう。 さて、私たちの要件は、これらの分離されたリストを2つの異なるファイルに入れる必要があるということです。 http_urls.txt https_urls.txt。

複数のバッファを操作するには、 edit(e)コマンドを使用して、viのnamed-registersを使用してファイル間でテキストを転送できるようにします。

:e [file1 file2 ...]

そのため、viでは、編集のために別のファイルに切り替える前に、現在のファイルを保存する必要があります。 ただし、変更を保存したくない場合もあります。 そのような状況では、 ほら! 最後に書かれたバージョンに戻すにはファイルバッファの。

次に、 edit(e)コマンドを使用してURIを2つの異なるファイルに分離する方法を見てみましょう。

ビデオプレーヤー

メディアエラー:フォーマットがサポートされていないか、ソースが見つかりません

ファイルのダウンロード:https://www.baeldung.com/wp-content/uploads/sites/2/2020/05/vi-ex-buffers.mp4?_ = 13

00:00
00:00
00:00

 

7. .exrc環境ファイル

私たち一人一人が独自の働き方をしているので、私たちは確かにエディターのいくつかのパーソナライズが好きです。 viの場合、これを行う方法は.exrcファイルを使用することです。

vi編集セッションを調整する方法を見てみましょう。

7.1. setコマンド

名前が示すように、 setコマンドは、エディターの機能動作を制御するフラグと変数の値を設定するのに役立ちます。 さて、私たちの何人かは通常、左側に行番号を見たいと思っています。 それでは、各セッションで行番号を自動的に表示する方法を見てみましょう。

ビデオプレーヤー

メディアエラー:フォーマットがサポートされていないか、ソースが見つかりません

ファイルのダウンロード:https://www.baeldung.com/wp-content/uploads/sites/2/2020/05/vi-exrc-set.mp4?_ = 14

00:00
00:00
00:00

 

そのため、要件に応じて使用できるフラグがさらにあります。 これを行うには、exモードでsetコマンドで使用可能なすべてのオプションを表示できます。

:set all

7.2. 略語

キーストロークを節約するために、viでは.exrcファイル内に略語を定義できます。

ab <short-phrase> <expanded-text>

省略形を設定した後、省略形の単語を入力した後にスペースを押すと、挿入モードで使用できるようになります。ただし、単語全体として使用した場合にのみ展開され、別の単語の一部としては展開されません。語。

それでは、国コードの略語を定義して使用する方法を見てみましょう。

ビデオプレーヤー

メディアエラー:フォーマットがサポートされていないか、ソースが見つかりません

ファイルのダウンロード:https://www.baeldung.com/wp-content/uploads/sites/2/2020/05/vi-ex-ab.mp4?_ = 15

00:00
00:00
00:00

後で、で略語を削除したい場合は、unabコマンドを使用できます。

:unab <phrase>

7.3. キーマッピング

物事をより速く行うためのviのさらに別の便利な機能は、マップコマンドを使用してカスタムキーボードショートカットを定義する機能です。

map <NewKeySequence> <TargetKeySequence>

私たちの仕事では、コンマで区切られた大量のデータを処理する必要があるとしましょう。 では、1回のキーストロークを使用して、列データからカンマ区切りの値を生成できると便利ではないでしょうか。 さて、先に進んで、この動作をVキーに割り当てましょう。

map V :1,$-1s/$/,/^M :%j^M

最後に、これを実際に見てみましょう。

ビデオプレーヤー

 

注意する必要があります ^ Mは、キャリッジリターンキーストロークのテキスト表現を表します 、で書く必要があります .exrc の組み合わせとしてのファイルキー。

8. 結論

このチュートリアルでは、 we は、いくつかのテキスト編集の問題を解決することにより、viの基礎の強力な基盤を築きました。 そのため、viを使用することの最良の部分は、特定の問題を解決するための複数の方法が常に存在することです。 そして、私たち自身の創造性で新しいviトリックを発見することはとても楽しいです