Linux vi 文字編輯器操作說明
Linux vi 文字編輯器操作說明
簡介
習慣了視窗平台的文字編輯器操作,到了 linux terminal 上會手足無措嗎? 沒有notepad++,sublime,連gedit都沒有,怎麼看程式碼,怎麼查log,怎麼改設定檔?
滑鼠不能用,ctrl-c ctrl-v 不能用,編輯文字檔變成漫長的try-and-error?
介紹您在linux 上的文字編輯好夥伴 vi,只要記住幾個簡單的操作指令,讓你在terminal 上也能有如神助。
前言
所有的 Unix Like 系統都會內建 vi 文字編輯器,其他的文字編輯器則不一定會存在(如: emacs,pico,nano,joe 等),而vi 一般會有 vi 跟 vim 兩種不同版本,vim 可視為 vi 的進階版,甚至可以作為程式開發工具使用,但在某些地方會因為管理規則的關係,只允許使用vi,因此本文會以 vi 的操作方式為主。
另一個使用vi的原因是,當透過terminal 連上客戶端主機進行設定或是log檢查時,通常都不會有x-window 的環境,也就不會有圖形介面可以用, 故剩下唯一可以依靠的就是vi了。當然,你可以把想要檢查的log檔抓到本地端電腦上打開進行檢查,或是將想更改的設定檔抓到本地端電腦上,更改完後再上傳到主機上,但總是會多了一個檔案上傳/下載的動作,如果需要檢查的檔案數量變多,或是會即時的變動內容,就可能造成作業上的困難。
常用模式
vi 在使用時會分不同的模式,一般常用的有下列幾種
指令模式 (command mode):
進入 vi時是處於指令模式,只能下按鍵指令,不能輸入文字。
此模式下可以進行: 移動游標; 刪除、複製、貼上; 復原、重做; 區塊範圍 (選取、複製、貼上)。
編輯模式(insert mode):
在 指令模式輸入 i,o,a,r 即可進入編輯模式,編輯結束時按 Esc 會回到 指令模式。
插入功能:i、o、a; 取代功能:r。
命令列模式(command-line mode):
在 指令模式輸入 /,?,: 就會進入 命令列模式,畫面最下方一列會出現輸入的指令,可下指令。一樣按 Esc 可回 指令模式。
此模式下可以進行: 搜尋、取代; 儲存、離開、讀入檔案; 顯示行號; 多檔案編輯。
新手常犯的錯誤是,一進 vi 後,就先按 i 進入編輯模式,再用方向鍵移到需要編輯的地方進行編輯,這樣其實是比較慢的做法,如果先用指令定位或搜尋找到要編輯的地方,再開始編輯,會省下許多時間。
一般會盡量讓vi 處於指令模式,以避免不小心更改到檔案內容。 換另外一種說法,只有在需要進行編輯時,才進入編輯模式。不知道目前到底是處於哪一種模式下? 只要看一下螢幕上最後一列,如果出現 – INSERT – 或是 – REPLACE – 那就是在編輯模式,如果輸入的指令會出現在最後一列上,那就是命令列模式,想要回到指令模式,只要按 ESC即可。
常用指令
以下簡介操作時的常用指令
開啟檔案:
動作 |
指令 |
備註 |
由命令列來開檔 |
$ vi filename |
|
開檔後游標會落在檔案最後一行的行尾 |
$ vi + filename |
方便由檔案結尾處繼續編輯 |
開檔後游標會落在第 n 行的行首 |
$ vi +n filename |
|
開檔後游標就會落在第一個找到的 string 上 |
$ vi +/string filename |
可以按 n 繼續找 下一個 |
一次開啟多個檔 |
$ vi 1.txt 2.txt 3.txt |
稱為 argument list |
多檔編輯時,可用切換檔案指令 |
:n 編輯下一個檔案。 :2n 編輯下二個檔案。 :N 編輯前一個檔案。 |
只能用於 argument list 的情形 |
進入 vi 後再開檔 |
進入 vi 後,使用 :e filename |
若filename 不存在,會開一個以 filename 為名的新檔案 |
編輯前一個檔案
|
:e# 或 Ctrl-^ |
用於同時編輯兩個檔案,或將檔案一的部分內容複製到檔案二時相當好用。 |
編輯檔案:
進入 vi 後,按 i,o,a,r 進入 編輯模式,就可以進行檔案編輯。
vi 中游標的移動可以由方向鍵來移動。Backspace 鍵可消去前一個字元。Del 鍵可刪除游標所在處的字元。
基本游標移動指令
動作 |
指令 |
備註 |
向左移動 |
h |
或 Backspace 或方向鍵 |
向下移動 |
j |
或 Enter 或 +,或方向鍵 |
向上移動 |
k |
或 方向鍵或 - |
向右移動 |
l |
Space 或方向鍵 |
向下翻頁(PageDown) |
Ctrl-f |
|
向上翻頁(PageUp) |
Crtl-b |
|
使用 hjkl 鍵的移動是為了使手不必離開鍵盤home row,以加快打字的速度,如果不習慣,可以使用方向鍵。
使用jk 及方向鍵的上下移動時,游標會盡量保持在同一欄位。
基本編輯指令
動作 |
指令 |
備註 |
在游標所在字元前開始輸入文字 |
i (小寫) |
insert |
在行首開始輸入文字
|
I (大寫) |
行首指第一個非空白字元處 |
在游標所在字元後開始輸入文字 |
a (小寫) |
append |
在行尾開始輸入文字 |
A (大寫) |
不管游標在此行的什麼地方,只要按 A 就會將游標移至行尾並進入編輯模式 |
在游標所在行下開一新行來輸入文字 |
o (小寫) |
Open |
在游標所在行上開一新行來輸入文字 |
O (大寫) |
|
將下一行與游標所在行合併 |
J(大寫) |
Joint 預設會消去游標所在行的行結束字元,且上下行合併處會加上一個空白字元 |
基本刪除指令
動作 |
指令 |
備註 |
刪除游標所在處之字元 |
x (小寫) |
亦可用 Del 鍵 |
刪除游標前之字元 |
X (大寫) |
|
刪除一整行 |
dd |
delete line |
刪除一個字 |
dw |
delete word |
刪至檔尾 |
dG |
|
刪至行尾 |
D |
或 d$(含游標所在處字元) |
基本複製指令
動作 |
指令 |
備註 |
複製游標所在行整行 |
yy |
或一個大寫Y |
複製多行 |
nyy 或 yny |
n 為欲複製的行數 |
貼至游標後 |
p (小寫) |
整行複製時,插入在下一行 |
貼至游標前 |
P (大寫) |
整行複製時,插入在上一行。 |
基本取代及還原指令
動作 |
指令 |
備註 |
取代游標所在處之字元 |
r |
replace |
由游標所在處起,取代字元至按 Esc 為止 |
R |
|
替換一個英文字 |
cw |
change word |
回覆上一次的編輯動作 |
u |
undo 傳統的 vi 僅支援一次 undo,vim則沒有限制 |
在游標沒離開本行之前,回復所有編輯動作 |
U |
|
存檔、離開:
文件編輯完畢後須先按 Esc 回到 指令模式,再進行存檔/離開動作。
動作 |
指令 |
備註 |
存檔 |
:w |
不會離開 vi |
離開 vi |
:q |
Quit 如檔案有異動但未存檔,會警告,且無法離開vi |
先存檔再離開vi |
:wq |
上述兩指令合用, 有順序性 |
捨棄所有修改,強制離開vi |
:q! |
|
多檔編輯時離開 vi |
:qa 或 :qa! |
|
存檔後離開 |
:x 或 ZZ |
如果檔案沒有修改,則不會做存檔的動作 |
另存新檔 |
:w 檔名 |
|
尋找、替換檔案內容
vi最特殊的地方是和正規表示式(regular expression)結合在一起。在執行如尋找或替換等動作時,依據正規表示式的 pattern,所有符合 pattern 的地方就會執行我們想要執行的動作。
尋找
在 指令模式 的情形下,按 / 或 ? 就會進入命令列模式,在左下角出現一個 /或 ?,然後輸入要尋找的字串,按下 Enter 就會開始尋找。
/ 是由前往後找,? 則是由後往前找。要找下一個的時候,只要輸入 n 即可,輸入N時則是反向尋找。
取代(substitute)
在 指令模式 的情形下,按 : 就會進入命令列模式,在左下角出現一個 :,然後依照替換格式輸入要尋找及替換的字串,按下 Enter 就會開始進行取代。
格式如下
:[range]s/pattern/string/[c,e,g,i]
欄位 |
說明 |
備註 |
range |
指定取代範圍 |
1,7 指從第一行至第七行,1,$ 指從第一行至最後一行,也可用 % 代表。 |
pattern |
要被取代掉的字串 |
可用一般字串或正規表示式來表示 |
string |
要將 pattern 取代的內容 |
|
c |
每次取代前會詢問是否確認取代 |
|
e |
不顯示 error |
|
g |
不詢問,指定取代範圍內全部替換 |
沒有加上g時只會取代範圍內第一個找到的位置 |
i |
不分大小寫 |
|
|
|
|
例如: 要將檔案中所有 abc 取代成為 123 :
:%s/abc/123/g
熟悉了上述的vi 指令後, 對使用vi 進行文字編輯會大有助益,接下來的指令會讓你更有效率的執行工作。
進階指令
下面列出在基本指令之外,可以在使用vi 時更有效率的指令,雖然熟悉這些指令需要時間,但可以選擇先熟悉對自己有幫助的指令,剩下的可以在有需要時上網搜尋,或透過主機上的man page 來查詢即可。
% |
代表目前編輯的檔案 |
# |
代表前一次編輯的檔案 |
ga |
把游標移到任一字元處,然後按ga,在狀態列就會顯示 該字元的10進位,16進位,8 進位的值。 |
. (dot, 英文句點) |
重複前次的編輯動作。只要是編輯動作(移動游標跟冒號命令都不算)都可以重複 |
0 |
數目字 0 ,或是 Home 鍵,移至行首,含空白字元 |
^ |
移至第一個非空白字元 |
$ |
移至行尾,或 End 鍵 |
G |
移至檔尾(最後一行的第一個非空白字元處),可移至指定行數之行首,如不指定行數,預設是最後一行 |
w |
移至次一個字字首 |
W |
同上,但會忽略一些標點符號 |
e |
移至前一個字字尾 (英文單字) |
E |
同上,但會忽略一些標點符號 |
b |
移至前一個字字首 |
B |
同上,但會忽略一些標點符號 |
H |
游標移動至螢幕頂第一個非空白字元 |
M |
游標移動至螢幕中間第一個非空白字元 |
L |
游標移動至螢幕底第一個非空白字元 |
n| |
移至從行首算起第 n 個字元(欄)處 |
:n |
移至第 n 行行首。或 nG |
) |
移至下一個句子首,句子是以 。 ! ? 為區隔 |
( |
移至上一個句子首 |
} |
移至下一個段落首,段落是以空白行為區隔 |
{ |
移至上一個段落首 |
% |
跳至配對的 {},[],() 處,檢查括號是否成對時相當好用 |
d1G |
刪至檔首 |
d0 |
刪至行首,或 d^(不含游標所在處字元) |
cc 或 S |
取代整行內容 |
~ |
游標所在處字元大小寫互換 |
C或 c$ |
取代至行尾,即游標所在處以後的字都會被替換 |
c0或 c^ |
取代至行首 |
s |
替換一個字元為輸入的字串 |
Crtl+r |
redo |
y^或 y0 |
複製至行首,不含游標所在處字元 |
y$ |
複製至行尾。含游標所在處字元 |
yw |
複製一個 word |
ynw |
複製n個字 |
yG |
複製至檔尾 |
y1G |
複製至檔首 |
"ayy |
將本行文字複製到 a 緩衝區(registers) |
"ap |
將 a 緩衝區的內容貼上 |
|
a 可為 26 個英文字母中的一個,小寫的話,會覆蓋掉緩衝區的內容,大寫的話,會把內容附加到原先緩衝區內容之後。 |
n"ayy |
複製n行內容至 a 緩衝區 |
n"Ayy |
複製n行附加到 a緩衝區現有內容之後 |
|
上述四個指令在用vi 開啟兩個檔案,並需要將A檔案部分內容複製到B檔案時特別好用,需搭配 :e# 指令使用 |
:reg |
列出所有緩衝區的代號及內容 |
可以在大部份的指令前加上數目字,代表重複次數,以下為使用範例
ndd |
刪除游標所在處(含)起算以下n行內容 |
nr |
按了 nr 後,鍵入一個字元,則游標處起n個字元皆會被所鍵入的字元取代 |
nJ |
將n行合併成一行 |
nx |
刪除n個字元 |
先輸入ni A 再按 Ecs |
插入n個 A |
緊急回復
vi 一開檔就會建立一個檔名為 。<filename>。swp 的隱藏檔,可用於回復檔案用,一般與所開啟的檔案位於同一目錄下,可以用 :set noswf 把 swap 的功能關掉,但如果編輯的檔案較大,則不建議關閉 swap,會很吃記憶體。
回復指令如下:
$ vi -r filename
或進入 vi 後,下 :recover filename
通常在vi不正常結束時才會需要進行緊急回復。
標示方法
visual mode底下可以對檔案的內容作標示的動作。
標示指令
v (小寫) |
字元標示,按下 v 後移動游標,游標經過的地方會被標示起來。再按一次 v 結束標示。同用 mouse 拉出的標示區。 |
V (大寫) |
行標示,按下 V 後會將游標所在處整行標示起來(包括行首前空白的部分),以上下鍵移動游標,可標示多行。再按一次 V結束標示。 |
Ctrl-v |
區塊標示,可縱向標示矩形區域。再按一次 Ctrl-v 結束標示。 |
d |
刪除標示區內容 |
y |
複製標示區內容 |
Esc 鍵 或Ctrl-c |
結束 v-mode |
"ay |
把標示區內容存於 a 緩衝區中 |
Shift-> |
標示區內容向右移一個 Tab |
Shift-< |
標示區內容向左移一個 Tab |
VI 客製化設定
Vi 有許多環境設定參數可供設定, 藉此可以讓使用者調整設定創造出一個使用者最順手的vi環境。
如何得知目前的設定
:set 或 :se 會顯示所有經過修改的部份,就是和預設值不一樣的部份。
:set all 顯示目前所有設定值內容。
:set option? 顯示 option 這設定的目前值。
:set option 直接線上設定,有些設定需加 = 後加上設定值內容。
:set nooption 取消該設定。
:set 可以同時設定多個參數。例如 :set autoindent noconfirm autowrite。
以下為更改設定的範例:
顯示行號
:set number 顯示行號。
:set nonumber 取消顯示行號。
依據程式相關語法顯示不同顏色
:syntax on
:syntax off