viで最高に格好いいインターフェースを持つのは検索であろう。 なんといっても、最短3ストロークで検索を実行できるのだから。
では、コマンド。
コマンド | 動作 |
---|---|
/「keyword」<return> |
「keyword」 を現在のカーソル位置から下方向に検索する |
?「keyword」<return> |
「keyword」 を現在のカーソル位置から上方向に検索する |
n |
直前の検索を繰り返す |
N |
直前の検索を逆方向に繰り返す |
「/」
または「?」
打って、キーワード打って、リターン打って、終わり。
すげぇ簡単だ・・・しびれる。
とりあえずこの2つのどちらかで一回検索してみて、
それが望んだものでなければnN
をガシガシ押して次候補を探していく、
という流れになる。
では実際に打ってみる。次の例文を考えよう。 カーソルは中央付近のuにある。
Eh-ya-ya-ya-yahaah - e'yayayayaaaa ... ngh'aaa ... ngh'aaa ... h'yuh ... h'yuh ... HELP! HELP! ... ff-ff-ff-FATHER! FATHER! YOG-SOTHOTH!
打ち込むコマンドはこんなの。
/YOG<return>
/HELP<return>n
?ya<return>nnn
?h'<return>N
カーソルがどこに跳ぶか考えてみてくれい・・・・・・では、結果。
1.は前方検索。前を見て一番近くにあるYOGにマッチする。
2.もやはり前方。/HELP
の時点で最初に現れるHELPに移動するが、次のnにより次候補に跳んで、2つめのHELPの位置に落ち着く。
3.は後方検索かつ4つ先(?, n, n, n
で4)の候補まで移動。
4.は後方検索なので一度2文字手前のh'
にマッチするのだが、
その後N
で逆方向に跳ぶよう指示してあるので結局前方にあるh'ynhにマッチする。
注意すべきはnが前方向、Nが後方向の再検索という機能ではない、という点である。 あくまでnが進行方向、Nが逆方向になる。 つまり、/で検索した後であればnで前、Nで後ろを探すが、 ?の使用後はnで後ろ、Nで前を探す。
大変便利なことに、検索キーワードには正規表現を適用できる
(正確には、正規表現しか受け付けない。普通の文字列とて立派な正規表現である)。
例えば、[Kk]eyword
という指定をすれば、keywordとKeywordの両方にマッチするし
hoge$
と指定すれば行末にhogeと入力されている部分にマッチする。
正規表現についての説明はそれだけでこのコンテンツを遙かに上回る文章量になるので割愛。
・・・私もあんまり詳しくないし。
正規表現は、是非覚えておくことを勧めるが、別に知らなくても検索はできるので強要する気もない。
ただし、覚えなくても、注意しなければならない事柄がある。
というのは、正規表現で特殊文字(メタ文字という)扱いになる[ ] * . + ^ $ &
等は、
そのままではその文字自体をキーにすることができないのである。
例えばx*y
という文字列を探そうとして/x*y
のように指定してもマッチしない。
x*
は「0個以上のxがある」という意味の正規表現であると見なされるため、
マッチするのはy、xy、xxy等である。
狙い通りに検索するには、/x\*y
のように\
を特殊文字の頭に付加しなければならない
(エスケープする、という)。
普通の文字に\
を付加しても無視されるだけなので、怪しいと思う文字にはとにかくつけてみると良い。
検索にマッチした文字列を任意の文字列と入れ替える、 というまぁエディタなら持っていて当然かつ重要な機能である。
置換は検索を拡張したような機能だが、操作するモードは検索と異なりexモードである。 以下、こまんどぉ。
コマンド | 動作 |
---|---|
:「lineno」s/「before」/「after」/[g]<return> |
「lineno」 行目で最初に現れる文字列「before」 を文字列「after」 に置換する。
最後のgは任意で、これを付加した場合はその行に現れる全ての「before」 を置換する
|
:「start」,「end」s/「before」/「after」/[g]<return> |
置換範囲が「start」 行目から「end」 行目までになる他は、上記と同様。 |
:「start」,$s/「before」/「after」/[g]<return> |
置換範囲が「start」 行目からファイルの最終行になる他は、上記と同様。 |
:%s/「before」/「after」/[g]<return> |
置換範囲がファイル全体になる他は、上記と同様。 |
・・・というコマンド共を見てもいまいちピンと来ないと思われる。 ピンと来る強者はおそらくsedやperlなどをバリバリにつかっているタイプだと思うが、 まぁあんな感じである。 では、例などを。ちと長めだが、これまで同様意味は考えなくてよし。
1: BE IT KNOWN THAT YE ARE TRESPASSING ON
THE PROPERTY OF THE ARCH-MAGE WERDNA.
THERE IS NO POSSIBLE WAY THAT YE CAN
POSSIBLY GET THROUGH MY DEFENSES,
2: LET ALONE DEFEAT ME IN BATTLE! SO SURE AM
I OF THIS THAT I GIVE YOU THIS CLUE,
"CONTRA-DEXTRA AVENUE"
PS - TREBOR SUX
太字になっている「1:」「2:」は行番号である。 つまり、この文は2行からなっている。
で、この文中の「YE」を「YOU」に変えたいとする。 ここで、次のようにコマンドを打つと・・・。
:1,2s/YE/YOU/
「1〜2行目に現れるYEをYOUに置換せよ」という操作である。 結果、こうなる。
1: BE IT KNOWN THAT YOU ARE TRESPASSING ON
THE PROPERTY OF THE ARCH-MAGE WERDNA.
THERE IS NO POSSIBLE WAY THAT YE CAN
POSSIBLY GET THROUGH MY DEFENSES,
2: LET ALONE DEFEAT ME IN BATTLE!
SO SURE AM I OF THIS THAT I GIVE YOU THIS CLUE,
"CONTRA-DEXTRA AVENUE"
PS - TREBOR SUX
反転している部分が置換された文字列である。 今回の場合は置換コマンドの最後に「g」を付加していないので、 1行目の最初に現れる「YE」しか置換しない。 そのあともう一つ「YE」は現れるが、そのままである。 とにかく全ての「YE」を置換したい場合は「g」を付加すれば・・・。
:1,2s/YE/YOU/g
根こそぎ置換されて、次のようになる。
1: BE IT KNOWN THAT YOU ARE TRESPASSING ON
THE PROPERTY OF THE ARCH-MAGE WERDNA.
THERE IS NO POSSIBLE WAY THAT YOU CAN
POSSIBLY GET THROUGH MY DEFENSES,
2: LET ALONE DEFEAT ME IN BATTLE!
SO SURE AM I OF THIS THAT I GIVE YOU THIS CLUE,
"CONTRA-DEXTRA AVENUE"
PS - TREBOR SUX
まぁ、慣れてしまえばどうということもない。 ちなみに、編集中のファイルにこの2行しかないのであれば、 次のように置換範囲をファイル全体にしても同じ動作になる。
:%s/YE/YOU/
さらに、だいたい「YE」という文字は1行目にしか現れないので、 置換対象を1行目のみに絞ってもやはり結果は同じである。
:1s/YE/YOU/
検索同様、置換操作に置いても、正規表現を使用できる。 さらに、正規表現に前方参照(back referrence)なる技を併用すると、 かなり高度な置換が可能になる。 この方法については、後ほど別途述べたい。