引言
Vi 最初是由 Bill Joy 在 1976 年編碼實現的。而 Vim (Vi IMproved) 則是改進的 Vi,由 Bram Moolenaar 在 1991 年開發併發布。Vi/Vim 是所有 Unix/Linux 操作系統默認配備的編輯器。因其強大的功能和高效的操作,Vi/Vim 也成爲衆多 Unix/Linux 用戶、管理員必須掌握並熟練使用的編輯工具之一。尤其是在沒有圖形界面的情況下,更是離不開 Vi/Vim。Vi/Vim 命令非常多、用法極爲靈活,掌握起來有一定的難度。詳細介紹 Vi/Vim 使用方法的文章有很多,因而本文就不一一述及 Vi/Vim 的諸多功能及命令。本文作者將結合自己的使用經驗,分七個方面着重介紹哪些原則、途徑或命令能快速提高 Vi/Vim 文件編輯效率,從而達到事半功倍的效果。本文述及的途徑或命令均只針對系統默認配置的 Vi/Vim。關於 Vi/Vim 各種定製後的功能不在本文討論範圍之列。(注:本文中提到的所有命令均在 Red Hat Enterprise Linux Server release 6.1 上測試通過。)
Vi/Vim 版本的選擇
“工欲善其事,必先利其器”。在 Vi/Vim 版本的選擇上,原則是“能用 Vim 就不要使用 Vi;能用最新版就不要守着舊版本”。Vim 提供的功能和特性要比 Vi 多得多,如語法加亮着色功能等。就使用效果及效率來說,編輯同樣的文件,使用 Vim 更勝一籌;就版本來說,新版的往往會修復舊版的一些缺陷及不足。這就要求我們在可能的情況下一定要使用最新版的 Vim。
小技巧:
在 Linux 下,如果以 root 用戶登錄系統的話,通過 vi 命令打開的 Vim 編輯器往往只加載最基本的功能,像語法加亮着色的功能基本上沒有。在 root 用戶下使用 Vim 所有功能的技巧是用 vim 命令打開 Vim 編輯器。
啓動及關閉 Vi/Vim
打開及關閉 Vi/Vim 的方法有很多,既可以只啓動 Vi/Vim 編輯器本身,也可以在啓動 Vi/Vim 編輯器的同時打開一個或多個文件;既可以放棄存盤退出,也可以只保存文件的一部分。以下爲相關命令列表:
表 1. 啓動及關閉 Vi/Vim 的基本命令
功能 | 命令 | 說明 |
---|---|---|
啓動 |
vi 打開 Vi/Vim vi <file> 打開 Vi/Vim 並加載文件 <file> |
|
退出 |
ZQ 無條件退出 :q! 無條件退出 ZZ 存盤並退出 :wq 存盤並退出 |
|
保存部分文件 |
:m,nw <file> 將 m 行到 n 行部分的內容保存到文件 <file> 中 :m,nw >> <file> 將 m 行到 n 行的內容添加到文件 <file> 的末尾 |
掌握並熟練這些基本命令是使用 Vi/Vim 的基本要求。只有這樣,才能在實際使用過程中做到按需選擇,靈活使用,提高 Vi/Vim 的使用效率。需要說明的一點是:在使用 Vi/Vim 的時候,有時想臨時退出 Vi/Vim,轉到 shell 環境裏去做一些操作,等這些操作結束後,再繼續回到剛纔的 Vi/Vim 狀態。針對這一經常碰到的現實需求,很多人在大多數情況下會將保存退出 Vi/Vim,進入 shell 執行操作,然後再重新打開剛纔編輯的文件。其實這是一個很低效的方法,因爲再次打開需要重新定位剛纔編輯的地方,麻煩不說,Vi/Vim 編輯器的狀態也完全不一樣了。其實,有兩種方法可以可以實現臨時退出 Vi/Vim、進入 shell 環境後再回來的要求:
方法一:使用 Ctrl-z 以及 fg 這兩個命令組合。
這一解決方法主要利用了 Linux/Unix 的作業機制。具體原理是:Ctrl-z 命令將當前的 Vi/Vim 進程放到後臺執行,之後 shell 環境即可爲你所用;fg 命令則將位於後臺的 Vi/Vim 進程放到前臺執行,這樣我們就再次進入 Vi/Vim 操作界面並恢復到原先的編輯狀態。
方法二:使用行命令 :sh。
在 Vi/Vim 的正常模式下輸入 :sh即可進入 Linux/Unix shell 環境。在要返回到 Vi/Vim 編輯環境時,輸入 exit 命令即可。
這兩種方法實現機制不一定,但效果一樣,都非常快捷有效。
移動光標
Vi/Vim 中關於光標移動的命令非常多,這也是很多人經常困惑並且命令用不好的地方之一。其實 Vi/Vim 中很多命令是針對不同的操作單位而設的,不同的命令對應不同的操作單位。因而,在使用命令進行操作的時候,首先要搞清楚的就是要採用哪種操作單位,也就是說,是要操作一個字符,一個句子,一個段落,還是要操作一行,一屏、一頁。單位不同,命令也就不同。只要單位選用得當,命令自然就恰當,操作也自然迅速高效;否則,只能是費時費力。這也可以說是最能體現 Vi/Vim 優越於其它編輯器的地方之一,也是 Vi/Vim 有人愛有人恨的地方之一。在操作單位確定之後,纔是操作次數,即確定命令重複執行的次數。要正確高效的運用 Vi/Vim 的各種操作,一定要把握這一原則:先定單位再定量。操作對象的範圍計算公式爲:操作範圍 = 操作次數 * 操作單位。比如:5h 命令左移 5 個字符,8w 命令右移 8 個單詞。
注:有些操作單位(如文件)是不能加操作次數。具體說明請參考 Vi/Vim 使用手冊。
Vi/Vim 中操作單位有很多,按從小到大的順序爲(括號內爲相應的操作命令):字符(h、l)→ 單詞 (w、W、b、B、e) → 行 (j、k、0、^、$、:n) → 句子((、))→ 段落({、})→ 屏 (H、M、L) → 頁(Ctrl-f、Ctrl-b、Ctrl-u、Ctrl-d) → 文件(G、gg、:0、:$)。
具體命令解釋如下:
表 2. 移動光標的基本命令
操作單位 | 命令 | 說明 |
---|---|---|
字符 |
h 左移一字符 l 右移一字符 |
|
單詞 |
w/W 移動到下一單詞的開頭 b/B 移動到上一單詞的開頭 e/E 移動到光標所在單詞的末尾 |
W、B、E 命令操作的單詞是以空白字符(空格、Tab)分隔的字串,比如字符串“str1-str2 str3-str4”,對 W、B、E 命令來說是兩個單詞,而對 w、b、e 命令來說則是四個單詞。 |
行 |
j 下移一行 k 上移一行 0 移到當前行開頭 ^ 移到當前行的第一個非空字符 $ 移到當前行末尾 :n 移動到第 n 行 |
0 爲數字零(zero) |
句子 |
) 移動到當前句子的末尾 ( 移動到當前句子的開頭 |
|
段落 |
} 移動當前段落的末尾 { 移到當前段落的開頭 |
|
屏 |
H 移動到屏幕的第一行 M 移動到屏幕的中間一行 L 移動到屏幕的最後一行 |
|
頁 |
Ctrl-f 向前滾動一頁 Ctrl-b 向後滾動一頁 Ctrl-u 向前滾動半頁 Ctrl-d 向後滾動半頁 |
|
文件 |
G 移動到文件末尾 gg 移動到文件開頭 :0 移動到文件第一行 :$ 移動到文件最後一行 |
0 爲數字零(zero) |
除了這些基本單位之外,還有 %(跳轉到與之匹配的括號處),`.(跳轉到最近修改過的位置並定位編輯點),'.(跳轉到最近修改過的位置但不定位編輯點)這三個命令也非常重要,在 Vi/Vim 中靈活使用會極大提高效率。% 除用於光標移動之後,還可用於檢測源碼中各種括號的匹配情況。
文本編輯
與光標移動一樣,Vi/Vim 中關於編輯操作的命令也比較多,但操作單位要比移動光標少得多。按從小到大的順序爲(括號內爲相應的操作命令):字符 (x、c、s、r、i、a)→ 單詞 (cw、cW、cb、cB、dw、dW、db、dB) → 行 (dd、d0、d$、I、A、o、O) → 句子((、))→ 段落({、})。這些操作單位有些可以加操作次數。操作對象的範圍計算公式爲:操作範圍 = 操作次數 * 操作單位。比如:d3w 命令刪除三個單詞,10dd 命令刪除十行。
具體命令解釋如下:
表 3. 文本編輯的基本命令
操作單位 | 命令 | 說明 |
---|---|---|
字符 |
x 刪除光標位置的字符 c 更改當前字符並進入插入模式 s 替換光標位置的字符並進入插入模式 r 替換光標位置的字符但不進入插入模式 i 在當前位置的字符之前進入插入模式 a 在當前位置的字符之後進入插入模式 |
|
單詞 |
cw/cW 刪除當前單詞從光標開始的部分並進入插入模式 cb/cB 刪除當前單詞從光標所在位置至單詞開始的部分並進入插入模式 dw/dW 刪除當前單詞從光標開始的部分但不進入插入模式 db/dB 刪除當前單詞從光標所在位置至單詞開始的部分但不進入插入模式 |
cW、cB、dW、dB 命令操作的單詞是以空白字符(空格、Tab)分隔的字串,比如字符串“str1-str2 str3-str4”,對 cW,cB,dW,dB 命令來說是兩個單詞,而對 cw、cb、dw、db 命令來說則是四個單詞。 |
行 |
dd 刪除當前行 d0 刪除從當前光標開始到行末的內容 d$ 刪除從當前光標開始到行末的內容 I 在當前行的行首進入插入模式 A 在當前行的行尾進入插入模式 o 在當前行下方另起一行進入插入模式 O 在當前行上方另起一行進入插入模式 |
|
句子 |
d) 刪除當前句子從光標位置開始到句末的內容 d( 刪除當前句子從光標位置開始到句首的內容 |
|
段落 |
d} 刪除當前段落從光標位置開始到段末的內容 d{ 刪除當前段落從光標位置開始到段首的內容 |
除上述最基本的文本編輯命令這外,Vi/Vim 還提供了許多其它的編輯命令或相關組合。使用這些命令或相關組合往往在極大提高文本編輯的效率與速度。現將這些命令按功能列如表下:
表 4. 文本編輯的高效命令
功能 | 命令 | 說明 |
---|---|---|
複製與粘貼 |
yw 複製當前單詞從光標開始的部分 yy 複製光標所在行的所有字符 p 將最後一個刪除或複製文本放在當前字符 P 將最後一個刪除或複製文本放在當前字符之前 |
配合操作數使用可快速拷貝編輯文本 |
撤消與重做 |
u 撤消更改 Ctrl-R 重做更改 |
非常實用的一個命令 |
重複操作 | . 重複上次操作 |
|
交換相鄰字符或行 |
xp 交換光標位置的字符和它右邊的字符 ddp 交換光標位置的行和它的下一行 |
|
大小寫轉換 |
~ 將光標下的字母大小寫反向轉換 guw 將光標所在的單詞變爲小寫 guw 將光標所在的單詞變爲小寫 gUw 將光標所在的單詞變爲大寫 guu 光標所在的行所有字符變爲小寫 gUU 光標所在的行所有字符變爲大寫 g~~ 光標所在的行所有字符大小寫反向轉換 |
|
取得外部輸入 |
: r!<cmd> 將命令 <cmd> 的輸出結果插入到當前光標所在位置 :r <file> 將文件 <file> 讀入到當前光標所在位置 |
|
排序 | :1,$!sort 將文件內的所有內容排序 | |
加入行號 |
:%!nl 在所有非空行前加入行號 :%!nl -ba 在所有行前加入行號 |
利用 Linux 命令 nl 來實現的 |
縮進 |
>> 右縮進(可配合操作數使用) << 左縮進(可配合操作數使用) |
配合操作數使用,在編輯源碼的時候非常有用。 |
自動補全 | Ctrl-p 自動補全 | 在編寫代碼的時候非常有用。比如,輸入 prin 後按 Ctrl-p 將自動幫你輸入 printf 函數名後面的部分,同時將相關備選函數在底下列出來。 |
顯示當前編輯文件名 | Ctrl-g 顯示當前編輯文件名及行數 | 可以在不退出 Vi/Vim 情況下了解當前編輯文件的信息 |
顯示字符內碼 | ga 顯示光標所在字符的內碼(包括十進制碼,十六進制碼以及八進制碼) | 顯示的內碼爲當前 encoding 下的內碼 |
文本搜索與替換
Vi/Vim 用於文本搜索的主要有下面的三個基本命令:
表 5. 文本搜索的基本命令
功能 | 命令 | 說明 |
---|---|---|
搜索 |
/ 在文件中向前搜索 ? 在文件中向後搜索 |
|
搜索下一個 |
n 搜索下一個 N 反向搜索下一個 |
|
除這三個基本命令之外,還有以下三個非常有效快捷的與搜索查找有關的命令:
表 6. 文本搜索的高效命令
功能 | 命令 | 說明 |
---|---|---|
快速搜索 |
* 在文件中向前搜索當前光標所在的單詞 # 在文件中向後搜索當前光標所在的單詞 |
非常快捷的搜索命令 |
顯示搜索命令歷史 |
q/ 顯示搜索命令歷史的窗口 q? 顯示搜索命令歷史的窗口 |
可以選擇重用以前用過的搜索查找命令 |
查找幫助 | Shift-k 查找光標所在命令或函數的 man 幫助 |
|
關於替換主是要結合搜索使用行命令來實現,命令格式爲:
:m,ns/str1/str2/g 將 m 行到 n 行中的字串 str1 全部替換爲字串 str2。
在衆多使用正則表達式進行替換的命令中,平時需要掌握的一個命令是如何快速去除 ^M 字符。在 Linux/Unix 系統中編輯 Windows 操作系統中生成的文件時,如果上傳時回車換行符處理不正確的話,用 Vi/Vim 打開經常會出現 ^M 字符。如果上傳的文件是 shell 腳本的話,即使賦予了正確的執行權限該腳本還是無法運行。這也是各種文件在 Linux/Unix 和 Windows 中傳輸經常會出現問題的地方之一。其實,在 Vi/Vim 中使用替換命令 :1,$s/^M//g即可以很容易地快速去掉 ^M 字符。這裏需要注意的是 ^M 是使用 Ctrl-v、Ctrl-m 輸入的。
執行外部命令
在 Vi/Vim 中還可以在正常模式下執行各種外部命令,命令格式如下:
表 7. 執行外部命令格式
功能 | 命令 | 說明 |
---|---|---|
執行外部命令 | :!<cmd> 執行外部命令 <cmd> | 在正常模式下輸入該命令 |
顯示命令行命令歷史 | q: 顯示命令行命令歷史的窗口 | 可以選擇重用以前用過的命令行命令 |
其中命令 q:會顯示使用過的行命令歷史,可以從中選擇重用以前用過的命令。這對於需要重複應用那些複雜的命令來說,非常方便快捷。
Vi/Vim 設置
Vi/Vim 有很多內部變量,可以根據需要進行相應的設置。變量類型不同往往設置方式也不一樣,簡單的只要設置特定的變量名即可,複雜的則需要指定和分配一個顯式值來設置變量。在實際應用中,如果有需要,請參考 Vi/Vim 的使用手冊。這裏主要列出大家經常使用並能提高編輯效率的一些設置命令:
表 8. Vi/Vim 設置命令
功能 | 命令 | 說明 |
---|---|---|
查看設置的當前值 |
:set all 查看 vi 或 Vim 中設置的所有選項的當前值 :set <option>? 查看特定選項 <option> 的當前值 |
|
設置行號顯示與否 |
:set number 顯示行號 :set no number 取消行號顯示 |
命令的簡寫形式: :set nu :set no nu |
設置自動縮進 |
:set autoindent 設置自動縮進 :set no autoindent 取消自動縮進設置 |
命令的簡寫形式: :set ai :set no ai |
設置縮進寬度 | :set shiftwidth=4 設置縮進寬度爲 4 |
命令的簡寫形式: :set sw=4 |
設置大小寫忽略與否 |
:set ignorecase 設置忽略大小 :set no ignorecase 取消忽略大小設置 |
命令的簡寫形式: :set ic :set no ic |
設置不可見字符顯示與否 |
:set list 顯示不可見字符 :set nolist 取消顯示不可見字符設置 |
在顯示不可見字符的情況下,TAB 鍵顯示爲 ^I,而 $ 顯示在每行的結尾。 |
在正常模式 (Normal mode) 時,執行這些設置命令只修改當前會話的設置,退出或重啓 Vi/Vim 這些設置就丟失了。要想保持住這些設置,就必須將這些設置寫入 Vi/Vim 的 vimrc 文件。對 Linux/Unix 操作系統來說,每個用戶的 vimrc 文件位於該用戶的主目錄下,文件名爲 .vimrc。Vi/Vim 在每次啓動的時候都會讀取用戶主目錄下的 vimrc 文件並據此設置 Vi/Vim 的使用環境。Vi/Vim 在安裝的同時也會安裝 vimrc 文件的一個示例 vimrc_example.vim 到 /usr/share/vim/vim<version> 目錄下。可以根據需要將這個示例文件拷貝到當前用戶的主目錄下並重命名爲 .vimrc,在此基礎上進行修改會相對容易一些。其它關於 Vi/Vim 的一些定製和鍵映射等相關設置基本上也是寫入用戶的 vimrc 文件中,更詳細的介紹請參考 Vi/Vim 的使用手冊。用戶也可以維護一個自己的 vimrc 文件,並將這個文件拷貝到自己的使用的環境中,保持不同環境中 Vi/Vim 特性的一致,以符合自己的使用習慣。