天天看點

vi編輯器的使用(2)

1.4 光标移動

vi編輯器中的很多指令都是基于光标目前位置的,是以,如何移動光标定位到所需要的位置是一項十分重要的工作,下面進行詳細介紹(如無特别說明,下面所講的指令都是在普通模式下執行)。

1. 向前移動字元

将光标向前移動一個字元可以使用指令為:l、Space鍵或方向鍵→。如果在指令前加一個數字n,就是将光标向前移動n個字元,例如:

#include<stdio.h>

假設目前光标在include中的字元c上,則使用5l後,光标将移動到e處。但是要注意:光标的移動不能超過目前行的末尾,當然如果給出的數字超過目前光标到行末尾的字元個數,那麼也隻能移到行尾。

2. 向後移動字元

将光标向後移動一個字元可以使用指令為:h、空格鍵或方向鍵←。同上面類似,如果在指令前加一個數字n,就将光标向後移動n個字元,而且光标不能超出行首。

3. 移到下一行

将光标移到下一行可以用的指令:+、Enter鍵、j、Ctrl+n或方向鍵↓。這些指令之間是有差别的,+和Enter鍵是将光标移到下一行的行首,其餘指令僅是移到下一行,所在的列不變。如果下一行比目前光标所在位置還短,則下标到行尾。

4. 移到上一行

将光标上移一行可以使用的指令:-、k、Ctrl+p或方向鍵↑。同上面的指令類似,-指令将光标移到上一行行首,而另外3個保持在同一列。

5. 移至行首

将光标移到目前行的行首使用的指令為0和^。這兩個指令在使用時的差别在于指令0是将光标移到目前行的第一個字元,不管它是否為空白符,而指令^将光标移到目前行的第一個非空白符。

6. 移至行尾

将光标移到目前行的行尾使用的指令為$。光标移至行尾後,停留在最後一個字元上,如果在該指令前加數字n,則光标将下移到n-1行的行尾。

7. 按詞前移

将光标按詞前移使用的指令為w和W。這兩個指令都是将光标向前移至下一個單詞的開頭,它們的差別在:指令w搜尋詞被定義為以标點符号或空白符(如制表符、換行符或空格符)分隔的字母或數字串;而指令W搜尋的詞被定義為非空白符字元串。例如有字元串:

echo l > /proc/sys/net/ipv4/conf/default/rp_filter

連續輸入指令w,光标從行首移動的位置為:e、l、>、/、p、s、…、/、r、r。

而指令W,光标從行首移動的位置為:e、l、>、/、r。

8. 按詞後移

将光标後移的指令是b和B,這兩個指令都是将光标後移至上一個單詞的開頭,同樣,他們對詞的定義是有差別的。

9. 移至詞尾

将光标移至目前字元所在詞尾的指令是e和E。它們對詞的定義與上面的類似。

10. 移至指定行

将光标移至指定行的開頭可以用指令如下:

  • :行号
  • 行号G

注意:第一個指令是在指令模式下執行的,而非普通模式。如果沒給出行号要顯示行号可以用如下指令顯示行号:

:set number

:ser nu

如圖1-11所示。

vi編輯器的使用(2)

圖1-11 在vi編輯器中顯示行号

将行号去掉可以使用指令:

:set nonumber

:set nonu

1.5 螢幕滾動

在檔案的編輯檢視過程中經常涉及螢幕的滾動問題。

在vi編輯器中,盡管可以使用鍵盤上的Page Up鍵和Page Dawn鍵來完成這些操作,甚至使用方向鍵↑和↓,但是效率比較低,下面來看看相關螢幕滾動的指令。

1. 向後滾動一屏

使用的指令為:Ctrl+f (滾屏後保留上一屏的最後兩行)

2. 向後滾動半屏

使用的指令為:Ctrl+d

3. 向前滾動一屏

使用的指令為:Ctrl+b

4. 向前滾動半屏

使用的指令為:Ctrl+u

5. 螢幕定位

使用指令zz将目前行置為螢幕正中央,使用指令zt會将目前行置為螢幕頂端,指令zb則會将目前行置于螢幕底端。

将螢幕直接定位于檔案第一屏或最後一屏也是經常遇到的問題,指令gg和G可以完成這樣的功能,使用完這些指令後,光标會定位到第一屏的第一行或最後一屏的最後一行上。

1.6 文本輸入、删除與修改

文本的輸入、删除與修改是檔案編輯的基本操作,其中大部分指令會将vi編輯器由普通模式切換為編輯模式,下面來介紹這些指令。

1. 插入指令

文本的插入指令為i和I。其中i是将其後輸出的字元插入到目前光标位置之前。指令I是将其後輸入的字元插入到目前光标所在行的行首。

2. 附加指令

附加文本的指令為a和A,其中指令a是将其後輸入的字元插入到目前光标位置之後,而指令A則是将其後輸入的字元追加到目前光标所在行的行尾。

3. 另起新行

另起新行的指令為o和O,其中指令o是在目前行的下面另起一行,指令O是在目前行的上面另起一行。新行建立完後,光标停留在新行行首,等待輸入文字。

4. 删除字元

删除字元的指令為x和X。其中指令x删除光标所在處的字元,而指令X删除光标前面的那個字元。如果之前給出一個數字n,則删除由光标所在字元開始向右的n個字元。

5. 删除文本對象

指令dd删除光标所在的行,指令D删除從光标所在位置開始到行尾的所有字元。

字母d可以與光标移動指令組合,例如:

  • d^:從光标位置删至行首,不包括光标位。
  • d$:從光标位置删至行尾,包括光标位,與D作用相同。
  • dG:删除目前行至檔案尾的内容。
  • Dgg:删除目前行至檔案頭的内容。

6. 修改指令

修改文本的指令為c、C和cc,它們的作用是用新輸入的文本取代原來的文本,這等價于将原來的文本删除後,利用指令i插入新的文本。

例如有一字元串:Hello World!

假設光标目前處在e處,輸入指令cw後,螢幕顯示如下:

H World!

此時光标處在H後的空格處,接着輸入文本i後按Esc鍵,螢幕顯示如下:

Hi World!

從上面可以看出,cw隻是修改光标目前位置到詞尾的字元,如果要修改整個單詞,可以使用指令caw。

C指令用來修改從光标位置到行尾的文本。如果在前面加一個數字n,那麼會把從目前光标位置至目前行下面的n-1行的内容都删除。

指令cc的功能和C相同,隻是修改的範圍不同,它修改光标所在的整行内容。

7. 取代指令

取代文本的指令為r和R。其中指令r是用其後輸入的單個字元取代光标所在的字元,如果在r前加一個數字n,則用其後輸入的單個字元取代光标所在處開始向後的n個字元。

R指令用其後輸入的文本取代光标所在處開始的若幹個字元,每輸入一個字元就取代原有的一個字元,多出的部分附加在後面。

1.7 複制與粘帖

vi編輯器中的緩沖區分為無名緩沖區和命名緩沖區。無名緩沖區以數字編号,一共有9個。前面講過可以使用删除指令x和dd來删除文本,其實被删除的内容還儲存在緩沖區中,最近一次删除的内容被儲存在緩沖區1中,次近的在緩沖區2中,以此類推,我們可以使用指令把他們提取回來。

1. 粘帖

粘帖緩沖區内容的指令是p和P,這兩個指令的差別是:指令p将文本放在目前行之下或目前光标之後,而指令P将文本放在目前行之上或光标之前。

例:使用vi編輯器打開如下檔案,然後進行删除和粘帖操作。

case

5:

case

4:

case

3:

case

2:

case

1:

case

0:

假設光标目前出在第2行,連續執行dd指令4次,螢幕如下:

case

5:

case

0:

輸入指令p,則在螢幕顯示如下:

case

5:

case

0:

case

1:

輸入指令”3p,則螢幕顯示如下:

case

5:

case

0:

case

1:

case

3:

注意:”3用來引用緩沖區3,單個雙引号後緊跟緩沖區的編号。

2. 複制

命名緩沖區是以字母a~z命名的,利用命名緩沖區可以很好地儲存若幹文本段,便于以後存取、移動或者重排。通路這些緩沖區時,和前面一樣,使用單個雙引号。

複制文本的指令有如下兩種格式:

yy

y<光标移動指令>

其中yy表示複制整行内容,而後者則通過光标移動指令來限定被複制的文本,如果沒有指定緩沖區的名字,文本就被插入到無名緩沖區中。如果用大寫字母表示緩沖區,則文本就附加到該緩沖區中,緩沖區中原有的内容不會被覆寫。

3. 不使用緩沖區的複制與移動

使用的指令為co,它的基本格式如下:

:<開始行>,<結束行> co <目标行>

這個指令在指令模式下執行,其中開始行和結束行辨別了文本複制的範圍,而目标行則是文本粘帖的位置。

1.8 查找與替換

1. 查找

/str向前查找字元串str,并将光标定位在str的第一個字母上,友善繼續操作,按下“/”鍵後光标跳到vi視窗的最後一行,然後等待輸入要查找的字元串,輸入完成後按Enter鍵開始搜尋,這時編輯器會高亮顯示搜尋結果。接下來可以使用指令n來實作光标在搜尋結果中移動。

指令?與/的工作方式相同,隻有搜尋方向相反。

使用上面介紹的指令,例如/the來查找時,可能需要搜尋比對單詞soothe和there,這時需要使用如下的形式:

/\<the\>

同理,要比對一行的開頭與結尾需要使用^和$字元,例如:

big$

這個指令隻能比對到一行末尾的單詞big。

:set ignorecase

如果不關心目标字元串中的大小寫,可以用上面的指令來設定。

:set nowrapscan

上面的指令是在輸入目标字元串的過程中vi就開始搜尋工作,即就是未完成輸入事就能找到目标。

2. 替換指令

使用的指令為s和S,其中指令s用随後輸入的文本替換光标所在處的字元。指令S将新輸入的文本替換目前整行。

3. 全局替換

全局替換指令有幾種常用的格式:

g/s1/s//s2/

将包含字元串s1的所有行中用字元串s2替換s1的首次出現,即就是将所有行中第一次出現的s1替換為s2。

例如程式如下:

int

main()

{

int

x;

for

(x=1;x<=10;x++)

printf

(“%d\n”,x);

return

0;

}

輸入指令g/x/s//abc/後,上面的程式變為:

int

main()

{

int

abc;

for

(abc=1;x<=10;x++)

printf

(“%d\n”,abc);

return

0;

}

可以看到每行中存在x的第一次出現處都被換為abc。

如果要将檔案中的所有字元串s1都替換為字元串s2,則使用如下指令:

g/s1/s//s2/g

int

main()

{

int

x;

for

(x=1;x<=10;x++)

printf

(“%d\n”,x);

return

0;

}

輸入指令g/x/s//abc/g後,上面的程式變為:

int

main()

{

int

abc;

for

(abc =1; abc <=10; abc ++)

printf

(“%d\n”, abc);

return

0;

}

可以看到所有的x都被替換為abc了。

g/s1/s

//s2/gc

該指令基本與上面的功能相同,隻是在替換之前給出提示要求确認,如果回答y則進行替換,否則不作替換。

     未完待續…

繼續閱讀