帶你掌握 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 系統