標籤:

帶你掌握 VI 編輯器的使用方法和技巧

來源:it笨笨 - 博客園

鏈接:vi編輯器的使用(1) - it笨笨 - 博客園

鏈接:vi編輯器的使用(2) - it笨笨 - 博客園

鏈接:vi編輯器的使用(3) - it笨笨 - 博客園

Linux 系統下的文本編輯器有很多種,包括圖形模式下的gedit、kwrite等,文本模式下的vi、vim(vi的增強版本)、emacs等。其中vi和emacs是Linux系統中最常用的兩個編輯器。本節主要介紹vi編輯器,主要內容包括:

  • vi編輯器的基本使用,包括vi的啟動與退出、工作模式的切換、游標的移動、屏幕的滾動、文本的插入與刪除、複製與粘帖、查找與替換等。

  • vi編輯器之程序編輯,包括程序設計中游標的跳轉、關鍵字的補全,以及代碼的縮進等。

希望通過本節的學習,能夠基本掌握vi編輯器的使用方法和相關技巧,能夠獨立完成程序源代碼的編輯和修改。

1、vi編輯器的基本使用

vi編輯器是Linux系統下的標準編輯器。雖然命令繁多複雜,並且絕大多數功能的輸入都依靠鍵盤來完成,但如果我們熟悉掌握之後就會發現vi編輯器的功能、效率等都是其他圖形界面編輯器無法比擬的,下面讓我們來揭開它的神秘面紗。

1.1 vi的啟動

在終端輸入命令vi,後面接著輸入想要創建或編輯的文件名,即可進入vi編輯器。

$ vi example.c

命令的結果如圖1-1所示:

圖1-1 vi編輯器新建文件

如果vi命令後面所輸入的文件不存在,則系統會自動創建一個以該字元串命名的文本文件。如上圖,游標停留在左上方,由於新建文件中沒有任何內容,所以每一行的開頭都為波浪線。窗口的底部為狀態欄,顯示當前編輯文件的相關信息。

打開文件後,游標停留在屏幕左上方。狀態欄顯示了當前編輯文件的文件名、行數以及字元數等信息,如圖1-2所示。

vi命令打開文件時還可以帶參數,這些參數用於修正vi的打開方式,主要包括如下:

  • -R 以只讀方式打開文件。

如果只需閱讀文件內容而不想對其進行修改時,可以使用這個參數,以防對文件的誤操作,如下:

$ vi –R example.c

運行命令如圖1-3所示。

圖1-2 vi編輯器打開文件

圖1-3 以只讀方式打開文件

  • -x 對文件進行加密。

該參數可以在保存文件時對其進行加密,以後每次打開都需要輸入密鑰,否則將出現亂碼。

如果在打開vi時,沒有給出文件名,也沒有給出任何參數,即:

$ vi

命令結果如圖1-4所示:

圖1-4 直接打開vi編輯器

此時,vi編輯器中所有行都為空,窗口中央給出的是vi編輯器的使用幫助,當用戶在vi中輸入文本或執行命令時,該幫助信息會自動消失。另外,如果以這種方式打開vi編輯器,在保存文件時,需要指定文件名。

1.2 vi的工作模式

vi有3種工作模式:普通模式、編輯模式和命令模式,這3種模式之間可以相互切換,如圖1-5所示。

圖1-5 vi編輯器的工作模式

1、普通模式

由Shell進入vi編輯器時,首先進入普通模式。在普通模式下,從鍵盤輸入任何字元都被當作命令來解釋。普通模式下沒有任何提示符,當輸入命令時立即執行,不需要回車,而且輸入的字元不會在屏幕上顯示出來。

普通模式下可以輸入命令進行游標的移動,字元、單詞、行的複製、粘帖以及刪除等操作。

2、編輯模式

編輯模式主要用於文本的輸入。在該模式下,用戶輸入的任何字元都被作為文件的內容保存起來,並在屏幕上顯示出來。在普通模式下,輸入a(附加命令)、c(修改命令)、i(插入命令)、o(另起新行)、r(取代命令)以及s(替換命令)都將進入編輯模式,此時vi窗口的最後一行會顯示「插入」。輸入i命令時屏幕上並無變化,但是通過執行i命令,編輯器由普通模式切換為編輯模式,如圖1-6所示。

圖1-6 編輯器由普通模式切換為編輯模式

接著輸入x=,屏幕顯示如圖1-7所示。

要返回到普通模式,只需按鍵Esc即可。

圖1-7 在編輯模式下輸入字元

3、命令模式

命令模式下,用戶可以對文件進行一些附加處理。儘管普通模式下的命令可以完成很多功能,但要執行一些如字元串查找、替換、顯示行號等操作還是必須要進入命令模式的。

在普通模式下輸入冒號即可進入命令模式,此時vi窗口的狀態行會顯示出冒號,等待用戶輸入命令。用戶輸入完成後,按回車執行,之後vi編輯器又返回到普通模式下。

1.3 文件的保存和退出

當編輯完畢,需要退出vi編輯器時,可以在命令模式下使用命令退出vi,返回到Shell。

1、保存退出

保存退出是指將緩衝區中的內容寫入文件,可以使用的命令為wq和x,如圖1-8所示。

圖1-8 vi編輯器的保存退出

2、強行退出

強行退出是指無條件退出,不把緩衝區中的內容寫入文件,所使用的命令為q!。其中感嘆號「!」表示不管文件是否被修改,放棄所修改的內容強行退出。

3、直接退出

直接退出和強行退出的區別是如果文件內容有修改則給出提示,如圖1-9所示,否則直接退出。直接退出使用的命令為q。

圖1-9 vi編輯器的直接退出

應該要注意一點,vi編輯器編輯文件時,用戶的操作都是基於緩衝區中的副本進行的。如果退出時沒有保存到磁碟,則緩衝區中的內容就會被丟失。所以,在退出vi編輯器時應該考慮是否需要保存所編輯的內容,然後再選擇執行合適的退出命令。保存命令為w,如果打開vi時沒有給出文件名,這時還需要給相互文件名。

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所示。

圖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編輯器打開如下文件,然後進行刪除和粘帖操作。

1

2

3

4

5

6

case 5:

case 4:

case 3:

case 2:

case 1:

case 0:

假設游標當前出在第2行,連續執行dd命令4次,屏幕如下:

1

2

case 5:

case 0:

輸入命令p,則在屏幕顯示如下:

1

2

3

case 5:

case 0:

case 1:

輸入命令」3p,則屏幕顯示如下:

1

2

3

4

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。

例如程序如下:

1

2

3

4

5

6

7

int main()

{

int x;

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

printf(「%d
」,x);

return 0;

}

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

1

2

3

4

5

6

7

int main()

{

int abc;

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

printf(「%d
」,abc);

return 0;

}

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

如果要將文件中的所有字元串s1都替換為字元串s2,則使用如下命令:

g/s1/s//s2/g

例如程序如下:

1

2

3

4

5

6

7

int main()

{

int x;

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

printf(「%d
」,x);

return 0;

}

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

1

2

3

4

5

6

7

int main()

{

int abc;

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

printf(「%d
」, abc);

return 0;

}

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

1

g/s1/s//s2/gc

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

2、vi編輯器之程序編輯

本小節主要介紹vi編輯器在程序設計中可以提高效率的幾項操作,包括游標的跳轉、關鍵字補全以及源代碼縮進等。

2.1程序中游標的跳轉

1、括弧之間的跳轉

命令%可以實現括弧之間的跳轉,轉到與當前游標下的括弧相匹配的一個括弧上,如果游標在「(」上,就會跳到與它匹配的「)」上,如果當前在「)」上,就向前自動跳到匹配的「(」上。看下面的例子:

1

2

3

4

5

6

7

int main ()

{

int x;

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

printf("%d
",x);

return 0;

}

假設游標處在第2行的行首,輸入命令%後,游標將跳到第7行的行首。

如果當前游標沒有停留在任何一個可用的括弧字元上,命令%也會向前為它找到一個,但只會在當前行內查找,所以如果當前游標位於上例中第4行的x<=10上時,命令%還是會向前先找到第一個「(」的。

2、局部變數和函數名的跳轉

命令gd可以在當前文件中對局部變數名或函數名進行搜索,並將游標定位在第一次出現的位置上,如圖1-13所示,在代碼第12行的sum變數上使用命令gd後,游標將定位在第4行的sum上。

這項功能對查找一些靜態的變數或函數比較有用。

3、查找全局標識符

當在編輯程序時,經常會想知道一個變數是被聲明為int型還是unsigned。解決這個問題的快速辦法就是使用命令[I,命令會列出所有包含該標識符的行,不光在當前文件中,也查找當前文件所包含的頭文件,以及被頭文件所包含的文件,以此類推。看下面例子:

1

2

3

4

5

6

7

8

9

10

/*file1.c*/

#include<stdio.h>

#include"yanyb.h"

int main ()

{

int x;

x=a;

printf("%d
",x);

return 0;

}

file1.c中包含了頭文件yanyb.h文件。

1

2

/*yanyb.h*/

int a=1;

在file1.c中的a上使用命令[I,會在窗口下方給出如下信息。

1

2

3

4

yanyb.h

1: 1 int a=1;

file1.c

2: 6 x=a;

上面列出的列表中每一行都有一個標號,如果要跳轉到某一項只要先輸入對應的標號即可:

3[<Tab>

2.2程序編輯過程中的關鍵字補全

很多的程序編輯器都提供了關鍵字補全功能,vi編輯器也不例外,相應的命令為Ctrl+p和Ctrl+n,這兩個命令之間的差別只是在於搜索的順序。

在源程序中輸入printf函數時,只輸入其中一部分,如圖1-14所示。

此時輸入Ctrl+n,屏幕中會出現相應的函數選項,此時可以使用上下方向鍵進行選擇,如下圖:

除了關鍵字補全外,還可以補全前面定義的變數或函數名。

2.3源代碼的縮進

縮進不僅可以增強代碼的可讀性,也利於錯誤的排除,vi編輯器中提供了自動縮進和手動縮進兩種功能,請看下面。

1、自動縮進

vi編輯器默認情況下可以自動完成縮進功能,對於縮進量可以在命令模式下使用如下命令進行設置。

: set cindent shiftwidth_=2

這裡將縮進設置為2個空格,即輸出的文件格式如下。

1

2

3

4

5

6

7

int main()

{

int x;

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

printf("%d
",x);

return 0;

}

如果設置為4,則輸出結果如下:

1

2

3

4

5

6

7

int main()

{

int x;

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

printf("%d
",x);

return 0;

}

2、手動縮進

如果接手一些縮進格式相當槽糕的代碼,或者要已有的代碼里增刪修補時,可能需要重新對代碼的縮進進行整理,這時可以使用命令「=」來實現。

看下面的例子:

1

2

3

4

5

6

7

int main()

{

int x;

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

printf("%d
",x);

return 0;

}

對於上面的代碼,可以在游標所在行執行==操作,對該行進行縮進。也可以使用命令=G,對當前所在行到文件底部所有進行縮進,輸出結果如下:

1

2

3

4

5

6

7

int main()

{

int x;

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

printf("%d
",x);

return 0;

}

可以看到,整段代碼實現了良好的縮進。


推薦閱讀:

(二十一)通俗易懂理解——Linux操作命令
如何高效地在 Linux 中搜索文件?
Ext2文件系統磁碟布局與管理
系統調用深度剖析(上)
Wiki 系統

TAG:Linux | Unix |