鍍金池/ 教程/ Linux/ layout: book-zh title: vi 簡(jiǎn)介
網(wǎng)絡(luò)系統(tǒng)
打印
重定向
使用命令
位置參數(shù)
權(quán)限
文本處理
疑難排解
layout: book-zh title: 自定制 shell 提示符
查找文件
layout: book-zh title: vi 簡(jiǎn)介
shell 環(huán)境
什么是 shell
編譯程序
鍵盤(pán)高級(jí)操作技巧
流程控制:case 分支
流程控制:if 分支結(jié)構(gòu)
layout: book-zh title: 軟件包管理
進(jìn)程
存儲(chǔ)媒介
格式化輸出
編寫(xiě)第一個(gè) Shell 腳本
啟動(dòng)一個(gè)項(xiàng)目
流程控制:while/until 循環(huán)
文件系統(tǒng)中跳轉(zhuǎn)
字符串和數(shù)字
讀取鍵盤(pán)輸入
歸檔和備份
探究操作系統(tǒng)
流程控制:for 循環(huán)
自頂向下設(shè)計(jì)
數(shù)組
操作文件和目錄
奇珍異寶
從 shell 眼中看世界
正則表達(dá)式

layout: book-zh title: vi 簡(jiǎn)介


layout: book-zh title: vi 簡(jiǎn)介

有一個(gè)古老的笑話,說(shuō)是一個(gè)在紐約的游客向行人打聽(tīng)這座城市中著名古典音樂(lè)場(chǎng)館的方向:

游客: 請(qǐng)問(wèn)一下,我怎樣去卡內(nèi)基音樂(lè)大廳?

行人: 練習(xí),練習(xí),練習(xí)!

學(xué)習(xí) Linux 命令行,就像要成為一名造詣很深的鋼琴家一樣,它不是我們一下午就能學(xué)會(huì)的技能。這需要 經(jīng)歷幾年的勤苦練習(xí)。在這一章中,我們將介紹 vi(發(fā)音“vee eye”)文本編輯器,它是 Unix 傳統(tǒng)中核心程序之一。 vi 因它難用的用戶(hù)界面而有點(diǎn)聲名狼藉,但是當(dāng)我們看到一位大師坐在鋼琴前開(kāi)始演奏時(shí),我們的確成了 偉大藝術(shù)的見(jiàn)證人。雖然我們?cè)谶@里不能成為 vi 大師,但是當(dāng)我們學(xué)完這一章后, 我們會(huì)知道怎樣在 vi 中玩“筷子”。

為什么我們應(yīng)該學(xué)習(xí) vi

在現(xiàn)在這個(gè)圖形編輯器和易于使用的基于文本編輯器的時(shí)代,比如說(shuō) nano,為什么我們還應(yīng)該學(xué)習(xí) vi 呢? 下面有三個(gè)充分的理由:

  • vi 很多系統(tǒng)都預(yù)裝。如果我們的系統(tǒng)沒(méi)有圖形界面,比方說(shuō)一臺(tái)遠(yuǎn)端服務(wù)器或者是一個(gè) X 配置損壞了的本地系統(tǒng),那么 vi 就成了我們的救星。雖然 nano 逐漸流行起來(lái),但是它 還沒(méi)有普及。POSIX,這套 Unix 系統(tǒng)中程序兼容的標(biāo)準(zhǔn),就要求系統(tǒng)要預(yù)裝 vi。

  • vi 是輕量級(jí)且執(zhí)行快速的編輯器。對(duì)于許多任務(wù)來(lái)說(shuō),啟動(dòng) vi 比起在菜單中找到一個(gè)圖形化文本編輯器, 再等待編輯器數(shù)倍兆字節(jié)的數(shù)據(jù)加載而言,要容易的多。另外,vi 是為了加快輸入速度而設(shè)計(jì)的。 我們將會(huì)看到,當(dāng)一名熟練的 vi 用戶(hù)在編輯文件時(shí),他或她的手從不需要移開(kāi)鍵盤(pán)。

  • 我們不希望其他 Linux 和 Unix 用戶(hù)把我們看作膽小鬼。

好吧,可能只有兩個(gè)充分的理由。

一點(diǎn)兒背景介紹

第一版 vi 是在1976由 Bill Joy 寫(xiě)成的,當(dāng)時(shí)他是加州大學(xué)伯克利分校的學(xué)生, 后來(lái)他共同創(chuàng)建了 Sun 微系統(tǒng)公司。vi 這個(gè)名字 來(lái)源于單詞“visual”,因?yàn)樗蛩阍趲в锌梢苿?dòng)光標(biāo)的視頻終端上編輯文本。在發(fā)明可視化編輯器之前, 有一次只能操作一行文本的行編輯器。為了指定一個(gè)修改,我們告訴行編輯器到一個(gè)特殊行并且 說(shuō)明做什么修改,比方說(shuō)添加或刪除文本。視頻終端(而不是基于打印機(jī)的終端,像電傳打印機(jī))的出現(xiàn) ,可視化編輯成為可能。vi 實(shí)際上整合了一個(gè)強(qiáng)大的叫做 ex 行編輯器, 所以我們?cè)谑褂?vi 時(shí)能運(yùn)行行編輯命令。

大多數(shù) Linux 發(fā)行版不包含真正的 vi;而是自帶一款高級(jí)替代版本,叫做 vim(它是“vi improved”的簡(jiǎn)寫(xiě))由 Bram Moolenaar 開(kāi)發(fā)的。vim 相對(duì)于傳統(tǒng)的 Unix vi 來(lái)說(shuō),取得了實(shí)質(zhì)性進(jìn)步。通常,vim 在 Linux 系統(tǒng)中是“vi”的符號(hào)鏈接(或別名)。 在隨后的討論中,我們將會(huì)假定我們有一個(gè)叫做“vi”的程序,但它其實(shí)是 vim。

啟動(dòng)和停止 vi

要想啟動(dòng) vi,只要簡(jiǎn)單地輸入以下命令:

[me@linuxbox ~]$ vi

一個(gè)像這樣的屏幕應(yīng)該出現(xiàn):

VIM - Vi Improved
....

正如我們之前操作 nano 時(shí),首先要學(xué)的是怎樣退出 vi。要退出 vi,輸入下面的命令(注意冒號(hào)是命令的一部分):

:q

shell 提示符應(yīng)該返回。如果由于某種原因,vi 不能退出(通常因?yàn)槲覀儗?duì)文件做了修改,卻沒(méi)有保存文件)。 通過(guò)給命令加上嘆號(hào),我們可以告訴 vi 我們真要退出 vi。

:q!

小貼示:如果你在 vi 中“迷失”了,試著按下 Esc 鍵兩次來(lái)找到路(回到普通模式)。

兼容模式

上面實(shí)例中的啟動(dòng)屏幕(來(lái)自于 Ubuntu 8.04),我們看到一行文字“以 Vi 兼容的模式運(yùn)行”。這意味著 vim 將以近似于 vi 常規(guī)的模式 運(yùn)行,而不是 vim 的高級(jí)規(guī)范。為了這章的目的,我們想要使用 vim 的高級(jí)規(guī)范。要想這樣做, 你有幾個(gè)選擇:

用 vim 來(lái)代替 vi。

如果命令生效,考慮在你的.bashrc 文件中添加別名 vi='vim'。

或者,使用這個(gè)命令在你的 vim 配置文件中添加一行:

echo "set nocp" >> ~/.vimrc

不同的 Linux 發(fā)行版其 vim 軟件包也迥然不同。一些發(fā)行版只是安裝了 vim 的最小版本, 其默認(rèn)只支持有限的 vim 特性。當(dāng)練習(xí)隨后的課程時(shí),你可能會(huì)遇到缺失的功能。 如果是這種情況,就安裝 vim 的完整版。

編輯模式

再次啟動(dòng) vi,這次傳遞給 vi 一個(gè)不存在的文件名。這也是用 vi 創(chuàng)建新文件的方法。

[me@linuxbox ~]$ rm -f foo.txt
[me@linuxbox ~]$ vi foo.txt

如果一切運(yùn)行正常,我們應(yīng)該獲得一個(gè)像這樣的屏幕:

....
"foo.txt" [New File]

每行開(kāi)頭的波浪號(hào)("~")指示那一行不存在文本。這表示我們有一個(gè)空文件。還沒(méi)有輸入任何字符?

學(xué)習(xí) vi 時(shí),要知道的第二件非常重要的事情是(知道了如何退出 vi 后)vi 是一個(gè)模式編輯器。當(dāng) vi 啟動(dòng)后,進(jìn)入 的是命令模式。這種模式下,幾乎每個(gè)按鍵都是一個(gè)命令,所以如果我們打算輸入字符,vi 會(huì)發(fā)瘋,弄得一團(tuán)糟。

插入模式

為了在文件中添加文本,首先我們必須進(jìn)入插入模式。按下"i"按鍵進(jìn)入插入模式。之后,我們應(yīng)該 在屏幕底部看到下面一行,如果 vi 運(yùn)行在高級(jí)模式下(這不會(huì)出現(xiàn)在 vi 兼容模式下):

-- INSERT --

現(xiàn)在我們能輸入一些文本了。試著輸入這些文本:

The quick brown fox jumped over the lazy dog.

按下 Esc 按鍵,退出插入模式并返回命令模式。

保存我們的工作

為了保存我們剛才對(duì)文件所做的修改,我們必須在命令模式下輸入一個(gè) ex 命令。 通過(guò)按下":"鍵,這很容易完成。按下冒號(hào)鍵之后,一個(gè)冒號(hào)字符應(yīng)該出現(xiàn)在屏幕的底部:

:

為了寫(xiě)入我們修改的文件,我們?cè)诿疤?hào)之后輸入"w"字符,然后按下回車(chē)鍵:

:w

文件將會(huì)寫(xiě)入到硬盤(pán),并且我們應(yīng)該在屏幕底部得到一個(gè)確認(rèn)信息,就像這樣:

"foo.txt" [New] 1L, 46C written

小貼示:如果你閱讀 vim 的文檔,你注意到(混淆地)命令模式被叫做普通模式,ex 命令 叫做命令模式。當(dāng)心。

移動(dòng)光標(biāo)

當(dāng)在 vi 命令模式下時(shí),vi 提供了大量的移動(dòng)命令,其中一些是與 less 閱讀器共享的。這里 列舉了一些:

表13-1: 光標(biāo)移動(dòng)按鍵
按鍵 移動(dòng)光標(biāo)
l or 右箭頭 向右移動(dòng)一個(gè)字符
h or 左箭頭 向左移動(dòng)一個(gè)字符
j or 下箭頭 向下移動(dòng)一行
k or 上箭頭 向上移動(dòng)一行
0 (零按鍵) 移動(dòng)到當(dāng)前行的行首。
^ 移動(dòng)到當(dāng)前行的第一個(gè)非空字符。
$ 移動(dòng)到當(dāng)前行的末尾。
w 移動(dòng)到下一個(gè)單詞或標(biāo)點(diǎn)符號(hào)的開(kāi)頭。
W 移動(dòng)到下一個(gè)單詞的開(kāi)頭,忽略標(biāo)點(diǎn)符號(hào)。
b 移動(dòng)到上一個(gè)單詞或標(biāo)點(diǎn)符號(hào)的開(kāi)頭。
B 移動(dòng)到上一個(gè)單詞的開(kāi)頭,忽略標(biāo)點(diǎn)符號(hào)。
Ctrl-f or Page Down 向下翻一頁(yè)
Ctrl-b or Page Up 向上翻一頁(yè)
numberG 移動(dòng)到第 number 行。例如,1G 移動(dòng)到文件的第一行。
G 移動(dòng)到文件末尾。

為什么 h,j,k,和 l 按鍵被用來(lái)移動(dòng)光標(biāo)呢?因?yàn)樵陂_(kāi)發(fā) vi 之初,并不是所有的視頻終端都有 箭頭按鍵,熟練的打字員可以使用規(guī)則的鍵盤(pán)按鍵來(lái)移動(dòng)光標(biāo),他們的手從不需要移開(kāi)鍵盤(pán)。

vi 中的許多命令都可以在前面加上一個(gè)數(shù)字,比方說(shuō)上面提到的"G"命令。在命令之前加上一個(gè) 數(shù)字,我們就可以指定命令執(zhí)行的次數(shù)。例如,命令"5j"導(dǎo)致 vi 向下移動(dòng)5行。

基本編輯

大多數(shù)編輯工作由一些基本的操作組成,比如說(shuō)插入文本,刪除文本和通過(guò)剪切和粘貼來(lái)移動(dòng)文本。 vi,當(dāng)然,以它自己的獨(dú)特方式來(lái)支持所有的操作。vi 也提供了有限的撤銷(xiāo)形式。如果我們按下“u” 按鍵,當(dāng)在命令模式下,vi 將會(huì)撤銷(xiāo)你所做的最后一次修改。當(dāng)我們?cè)囍鴪?zhí)行一些基本的 編輯命令時(shí),這會(huì)很方便。

追加文本

vi 有幾種不同進(jìn)入插入模式的方法。我們已經(jīng)使用了 i 命令來(lái)插入文本。

讓我們返回到我們的 foo.txt 文件中,呆一會(huì)兒:

The quick brown fox jumped over the lazy dog.

如果我們想要在這個(gè)句子的末尾添加一些文本,我們會(huì)發(fā)現(xiàn) i 命令不能完成任務(wù),因?yàn)槲覀儾荒馨?光標(biāo)移到行尾。vi 提供了追加文本的命令,明智地命名為"a"命令。如果我們把光標(biāo)移動(dòng)到行尾,輸入"a", 光標(biāo)就會(huì)越過(guò)行尾,vi 進(jìn)入插入模式。這樣就允許我們添加更多的文本:

The quick brown fox jumped over the lazy dog. It was cool.

記住按下 Esc 按鍵來(lái)退出插入模式。

因?yàn)槲覀儙缀蹩偸窍胍谛形哺郊游谋荆?vi 提供了一種快捷方式來(lái)移動(dòng)到當(dāng)前行的末尾,并且能添加 文本。它是"A"命令。試著用一下它,給文件添加更多行。

首先,使用"0"(零)命令,將光標(biāo)移動(dòng)到行首。現(xiàn)在我們輸入"A",來(lái)添加以下文本行:

The quick brown fox jumped over the lazy dog. It was cool.
Line 2
Line 3
Line 4
Line 5

再一次,按下 Esc 按鍵退出插入模式。

正如我們所看到的,大 A 命令非常有用,因?yàn)樵趩?dòng)插入模式之前,它把光標(biāo)移到了行尾。

打開(kāi)一行

我們插入文本的另一種方式是“打開(kāi)”一行。這會(huì)在存在的兩行之間插入一個(gè)空白行,并且進(jìn)入插入模式。 這種方式有兩個(gè)變體:

表13-2: 文本行打開(kāi)按鍵
命令 打開(kāi)行
o 當(dāng)前行的下方打開(kāi)一行。
O 當(dāng)前行的上方打開(kāi)一行。

我們可以演示一下:把光標(biāo)放到"Line 3"上,按下小 o 按鍵。

The quick brown fox jumped over the lazy dog. It was cool.
Line 2
Line 3

line 4
line 5

在第三行之下打開(kāi)了新的一行,并且進(jìn)入插入模式。按下 Esc,退出插入模式。按下 u 按鍵,撤銷(xiāo)我們的修改。

按下大 O 按鍵在光標(biāo)之上打開(kāi)新的一行:

The quick brown fox jumped over the lazy dog. It was cool.
Line 2

Line 3
Line 4
Line 5

按下 Esc 按鍵,退出插入模式,并且按下 u 按鍵,撤銷(xiāo)我們的更改。

刪除文本

正如我們期望的,vi 提供了各種各樣的方式來(lái)刪除文本,所有的方式包含一個(gè)或兩個(gè)按鍵。首先, x 按鍵會(huì)刪除光標(biāo)位置的一個(gè)字符??梢栽?x 命令之前帶上一個(gè)數(shù)字,來(lái)指明要?jiǎng)h除的字符個(gè)數(shù)。 d 按鍵更通用一些。類(lèi)似 x 命令,d 命令之前可以帶上一個(gè)數(shù)字,來(lái)指定要執(zhí)行的刪除次數(shù)。另外, d 命令之后總是帶上一個(gè)移動(dòng)命令,用來(lái)控制刪除的范圍。這里有些實(shí)例:

表13-3: 文本刪除命令
命令 刪除的文本
x 當(dāng)前字符
3x 當(dāng)前字符及其后的兩個(gè)字符。
dd 當(dāng)前行。
5dd 當(dāng)前行及隨后的四行文本。
dW 從光標(biāo)位置開(kāi)始到下一個(gè)單詞的開(kāi)頭。
d$ 從光標(biāo)位置開(kāi)始到當(dāng)前行的行尾。
d0 從光標(biāo)位置開(kāi)始到當(dāng)前行的行首。
d^ 從光標(biāo)位置開(kāi)始到文本行的第一個(gè)非空字符。
dG 從當(dāng)前行到文件的末尾。
d20G 從當(dāng)前行到文件的第20行。

把光標(biāo)放到第一行單詞“It”之上。重復(fù)按下 x 按鍵直到刪除剩下的部分。下一步,重復(fù)按下 u 按鍵 直到恢復(fù)原貌。

注意:真正的 vi 只是支持單層面的 undo 命令。vim 則支持多個(gè)層面的。

我們?cè)俅螆?zhí)行刪除命令,這次使用 d 命令。還是移動(dòng)光標(biāo)到單詞"It"之上,按下的 dW 來(lái)刪除單詞:

The quick brown fox jumped over the lazy dog. was cool.
Line 2
Line 3
Line 4
Line 5

按下 d$刪除從光標(biāo)位置到行尾的文本:

The quick brown fox jumped over the lazy dog.
Line 2
Line 3
Line 4
Line 5

按下 dG 按鍵刪除從當(dāng)前行到文件末尾的所有行:

~
....

連續(xù)按下 u 按鍵三次,來(lái)恢復(fù)刪除部分。

剪切,復(fù)制和粘貼文本

這個(gè) d 命令不僅刪除文本,它還“剪切”文本。每次我們使用 d 命令,刪除的部分被復(fù)制到一個(gè) 粘貼緩沖區(qū)中(看作剪切板)。過(guò)后我們執(zhí)行小 p 命令把剪切板中的文本粘貼到光標(biāo)位置之后, 或者是大 P 命令把文本粘貼到光標(biāo)之前。

y 命令用來(lái)“拉”(復(fù)制)文本,和 d 命令剪切文本的方式差不多。這里有些把 y 命令和各種移動(dòng)命令 結(jié)合起來(lái)使用的實(shí)例:

表13-4: 復(fù)制命令
命令 復(fù)制的內(nèi)容
yy 當(dāng)前行。
5yy 當(dāng)前行及隨后的四行文本。
yW 從當(dāng)前光標(biāo)位置到下一個(gè)單詞的開(kāi)頭。
y$ 從當(dāng)前光標(biāo)位置到當(dāng)前行的末尾。
y0 從當(dāng)前光標(biāo)位置到行首。
y^ 從當(dāng)前光標(biāo)位置到文本行的第一個(gè)非空字符。
yG 從當(dāng)前行到文件末尾。
y20G 從當(dāng)前行到文件的第20行。

我們?cè)囍鲂?fù)制和粘貼工作。把光標(biāo)放到文本第一行,輸入 yy 來(lái)復(fù)制當(dāng)前行。下一步,把光標(biāo)移到 最后一行(G),輸入小寫(xiě)的 p 把復(fù)制的一行粘貼到當(dāng)前行的下面:

The quick brown fox jumped over the lazy dog. It was cool.
Line 2
Line 3
Line 4
Line 5
The quick brown fox jumped over the lazy dog. It was cool.

和以前一樣,u 命令會(huì)撤銷(xiāo)我們的修改。光標(biāo)仍然位于文件的最后一行,輸入大寫(xiě)的 P 命令把 所復(fù)制的文本粘貼到當(dāng)前行之上:

The quick brown fox jumped over the lazy dog. It was cool.
Line 2
Line 3
Line 4
Line 5
The quick brown fox jumped over the lazy dog. It was cool.

試著執(zhí)行上表中一些其他的 y 命令,了解小寫(xiě) p 和大寫(xiě) P 命令的行為。當(dāng)你完成練習(xí)之后,把文件 恢復(fù)原樣。

連接行

vi 對(duì)于行的概念相當(dāng)嚴(yán)格。通常,不可能把光標(biāo)移到行尾,再刪除行尾結(jié)束符(回車(chē)符)來(lái)連接 當(dāng)前行和它下面的一行。由于這個(gè)原因,vi 提供了一個(gè)特定的命令,大寫(xiě)的 J(不要與小寫(xiě)的 j 混淆了, j 是用來(lái)移動(dòng)光標(biāo)的)把行與行之間連接起來(lái)。

如果我們把光標(biāo)放到 line 3上,輸入大寫(xiě)的 J 命令,看看發(fā)生什么情況:

The quick brown fox jumped over the lazy dog. It was cool.
Line 2
Line 3 Line 4
Line 5

查找和替換

vi 有能力把光標(biāo)移到搜索到的匹配項(xiàng)上。vi 可以在單一行或整個(gè)文件中運(yùn)用這個(gè)功能。 它也可以在有或沒(méi)有用戶(hù)確認(rèn)的情況下實(shí)現(xiàn)文本替換。

查找一行

f 命令查找一行,移動(dòng)光標(biāo)到下一個(gè)所指定的字符上。例如,命令 fa 會(huì)把光標(biāo)定位到同一行中 下一個(gè)出現(xiàn)的"a"字符上。在一行中執(zhí)行了字符的查找命令之后,通過(guò)輸入分號(hào)來(lái)重復(fù)這個(gè)查找。

查找整個(gè)文件

移動(dòng)光標(biāo)到下一個(gè)出現(xiàn)的單詞或短語(yǔ)上,使用 / 命令。這個(gè)命令和我們之前在 less 程序中學(xué)到 的一樣。當(dāng)你輸入/命令后,一個(gè)"/"字符會(huì)出現(xiàn)在屏幕底部。下一步,輸入要查找的單詞或短語(yǔ)后, 按下回車(chē)。光標(biāo)就會(huì)移動(dòng)到下一個(gè)包含所查找字符串的位置。通過(guò) n 命令來(lái)重復(fù)先前的查找。 這里有個(gè)例子:

The quick brown fox jumped over the lazy dog. It was cool.
Line 2
Line 3
Line 4
Line 5

把光標(biāo)移動(dòng)到文件的第一行。輸入:

/Line

然后鍵入回車(chē)。光標(biāo)會(huì)移動(dòng)到第二行。下一步,輸入 n,光標(biāo)移到第三行。重復(fù)這個(gè) n 命令,光標(biāo)會(huì) 繼續(xù)向下移動(dòng)直到遍歷了所有的匹配項(xiàng)。雖然目前,我們只是使用了單詞和短語(yǔ)來(lái)作為我們的查找 模式,但是 vi 允許使用正則表達(dá)式,一種強(qiáng)大的用來(lái)表示復(fù)雜文本模式的方法。我們將會(huì)在隨后 的章節(jié)里面詳盡地介紹正則表達(dá)式。

全局查找和替代

vi 使用 ex 命令來(lái)執(zhí)行查找和替代操作(vi 中叫做“替換”)。把整個(gè)文件中的單詞“Line”更改為“l(fā)ine”, 我們輸入以下命令:

:%s/Line/line/g

我們把這個(gè)命令分解為幾個(gè)單獨(dú)的部分,看一下每部分的含義:

條目 含義
: 冒號(hào)字符運(yùn)行一個(gè) ex 命令。
% 指定要操作的行數(shù)。% 是一個(gè)快捷方式,表示從第一行到最后一行。另外,操作范圍也 可以用 1,5 來(lái)代替(因?yàn)槲覀兊奈募挥?行文本),或者用 1,$ 來(lái)代替,意思是 “ 從第一行到文件的最后一行?!?如果省略了文本行的范圍,那么操作只對(duì)當(dāng)前行生效。
s 指定操作。在這種情況下是,替換(查找與替代)。
/Line/line 查找類(lèi)型與替代文本。
g 這是“全局”的意思,意味著對(duì)文本行中所有匹配的字符串執(zhí)行查找和替換操作。如果省略 g,則 只替換每個(gè)文本行中第一個(gè)匹配的字符串。

執(zhí)行完查找和替代命令之后,我們的文件看起來(lái)像這樣:

The quick brown fox jumped over the lazy dog. It was cool.
line 2
line 3
line 4
line 5

我們也可以指定一個(gè)需要用戶(hù)確認(rèn)的替換命令。通過(guò)添加一個(gè)"c"字符到這個(gè)命令的末尾,來(lái)完成 這個(gè)替換命令。例如:

:%s/line/Line/gc

這個(gè)命令會(huì)把我們的文件恢復(fù)先前的模樣;然而,在執(zhí)行每個(gè)替換命令之前,vi 會(huì)停下來(lái), 通過(guò)下面的信息,來(lái)要求我們確認(rèn)這個(gè)替換:

replace with Line (y/n/a/q/l/^E/^Y)?

括號(hào)中的每個(gè)字符都是一個(gè)可能的選擇,如下所示:

表13-5: 替換確認(rèn)按鍵
按鍵 行為
y 執(zhí)行替換操作
n 跳過(guò)這個(gè)匹配的實(shí)例
a 對(duì)這個(gè)及隨后所有匹配的字符串執(zhí)行替換操作。
q or esc 退出替換操作。
l 執(zhí)行這次替換并退出。l 是 “l(fā)ast” 的簡(jiǎn)寫(xiě)。
Ctrl-e, Ctrl-y 分別是向下滾動(dòng)和向上滾動(dòng)。用于查看建議替換的上下文。

如果你輸入 y,則執(zhí)行這個(gè)替換,輸入 n 則會(huì)導(dǎo)致 vi 跳過(guò)這個(gè)實(shí)例,而移到下一個(gè)匹配項(xiàng)上。

編輯多個(gè)文件

同時(shí)能夠編輯多個(gè)文件是很有用的。你可能需要更改多個(gè)文件或者從一個(gè)文件復(fù)制內(nèi)容到 另一個(gè)文件。通過(guò) vi,我們可以打開(kāi)多個(gè)文件來(lái)編輯,只要在命令行中指定要編輯的文件名。

vi file1 file2 file3...

我們先退出已經(jīng)存在的 vi 會(huì)話,然后創(chuàng)建一個(gè)新文件來(lái)編輯。輸入:wq 來(lái)退出 vi 并且保存了所做的修改。 下一步,我們將在家目錄下創(chuàng)建一個(gè)額外的用來(lái)玩耍的文件。通過(guò)獲取從 ls 命令的輸出,來(lái)創(chuàng)建這個(gè)文件。

[me@linuxbox ~]$ ls -l /usr/bin > ls-output.txt

用 vi 來(lái)編輯我們的原文件和新創(chuàng)建的文件:

[me@linuxbox ~]$ vi foo.txt ls-output.txt

vi 啟動(dòng),我們會(huì)看到第一個(gè)文件顯示出來(lái):

The quick brown fox jumped over the lazy dog. It was cool.
Line 2
Line 3
Line 4
Line 5

文件之間轉(zhuǎn)換

從這個(gè)文件轉(zhuǎn)到下一個(gè)文件,使用這個(gè) ex 命令:

:n

回到先前的文件使用:

:N

當(dāng)我們從一個(gè)文件移到另一個(gè)文件時(shí),如果當(dāng)前文件沒(méi)有保存修改,vi 會(huì)阻止我們轉(zhuǎn)換文件, 這是 vi 強(qiáng)制執(zhí)行的政策。在命令之后添加感嘆號(hào),可以強(qiáng)迫 vi 放棄修改而轉(zhuǎn)換文件。

另外,上面所描述的轉(zhuǎn)換方法,vim(和一些版本的 vi)也提供了一些 ex 命令,這些命令使 多個(gè)文件更容易管理。我們可以查看正在編輯的文件列表,使用:buffers 命令。運(yùn)行這個(gè) 命令后,屏幕頂部就會(huì)顯示出一個(gè)文件列表:

:buffers
1 #     "foo.txt"                 line 1
2 %a    "ls-output.txt"           line 0
Press ENTER or type command to continue

注意:你不同通過(guò):n 或:N 命令在由:e 命令加載的文件之間進(jìn)行切換。這時(shí)要使用:buffer 命令, 其后加上緩沖區(qū)號(hào)碼,來(lái)轉(zhuǎn)換文件。

從一個(gè)文件復(fù)制內(nèi)容到另一個(gè)文件

當(dāng)我們編輯多個(gè)文件時(shí),經(jīng)常地要復(fù)制文件的一部分到另一個(gè)正在編輯的文件。使用之前我們學(xué)到的 拉(yank)和粘貼命令,這很容易完成。說(shuō)明如下。以打開(kāi)的兩個(gè)文件為例,首先轉(zhuǎn)換到緩沖區(qū)1(foo.txt) ,輸入:

:buffer 1

我們應(yīng)該得到以下輸出:

The quick brown fox jumped over the lazy dog. It was cool.
Line 2
Line 3
Line 4
Line 5

下一步,把光標(biāo)移到第一行,并且輸入 yy 來(lái)復(fù)制這一行。

轉(zhuǎn)換到第二個(gè)緩沖區(qū),輸入:

:buffer 2

現(xiàn)在屏幕會(huì)包含一些文件列表(這里只列出了一部分):

total 343700
-rwxr-xr-x 1 root root    31316  2007-12-05  08:58 [
....

移動(dòng)光標(biāo)到第一行,輸入 p 命令把我們從前面文件中復(fù)制的一行粘貼到這個(gè)文件中:

total 343700
The quick brown fox jumped over the lazy dog. It was cool.
-rwxr-xr-x 1 root root    31316  2007-12-05  08:58 [
....

插入整個(gè)文件到另一個(gè)文件

也有可能把整個(gè)文件插入到我們所編輯的文件中。看一下實(shí)際操作,結(jié)束 vi 會(huì)話,重新 啟動(dòng)一個(gè)只打開(kāi)一個(gè)文件的 vi 會(huì)話:

[me@linuxbox ~]$ vi ls-output.txt

再一次看到我們的文件列表:

total 343700
-rwxr-xr-x 1 root root    31316  2007-12-05  08:58 [

移動(dòng)光標(biāo)到第三行,然后輸入以下 ex 命令:

:r foo.txt

這個(gè):r 命令(是"read"的簡(jiǎn)稱(chēng))把指定的文件插入到光標(biāo)位置之前。現(xiàn)在屏幕應(yīng)該看起來(lái)像這樣:

total 343700
-rwxr-xr-x 1 root root     31316 2007-12-05  08:58 [
....
The quick brown fox jumped over the lazy dog. It was cool.
Line 2
Line 3
Line 4
Line 5
-rwxr-xr-x 1 root root     111276 2008-01-31  13:36 a2p
....

保存工作

像 vi 中的其它操作一樣,有幾種不同的方法來(lái)保存我們所修改的文件。我們已經(jīng)研究了:w 這個(gè) ex 命令, 但還有幾種方法,可能我們也覺(jué)得有幫助。

在命令模式下,輸入 ZZ 就會(huì)保存并退出當(dāng)前文件。同樣地,ex 命令:wq 把:w 和:q 命令結(jié)合到 一起,來(lái)完成保存和退出任務(wù)。

這個(gè):w 命令也可以指定可選的文件名。這個(gè)的作用就如"Save As..."。例如,如果我們 正在編輯 foo.txt 文件,想要保存一個(gè)副本,叫做 foo1.txt,那么我們可以執(zhí)行以下命令:

:w foo1.txt

注意:當(dāng)上面的命令以一個(gè)新名字保存文件時(shí),但它并沒(méi)有更改你正在編輯的文件的名字。 如果你繼續(xù)編輯的話,你還是在編輯文件 foo.txt,而不是 foo1.txt。


拓展閱讀

即使把這章所學(xué)的內(nèi)容都加起來(lái),我們也只是學(xué)了 vi 和 vim 的一點(diǎn)兒皮毛而已。這里 有一些在線的資料,你可以用來(lái)繼續(xù) vi 學(xué)習(xí)之旅。

  • 學(xué)習(xí) vi 編輯器-一本來(lái)自于 Wikipedia 的 Wikibook,是一本關(guān)于 vi 的簡(jiǎn)要指南,并 介紹了幾個(gè)類(lèi)似 vi 的程序,其中包括 vim。它可以在以下鏈接中得到:

    http://en.wikibooks.org/wiki/Vi

  • The Vim Book-vim 項(xiàng)目,一本570頁(yè)的書(shū)籍,包含了(幾乎)所有的 vim 特性。你能在下面鏈接中找到它:

  • Wikipedia 上關(guān)于 Bill Joy 的文章,vi 的創(chuàng)始人。

    http://en.wikipedia.org/wiki/Bill_Joy

  • Wikipedia 上關(guān)于 Bram Moolenaar 的文章,vim 的作者:

    http://en.wikipedia.org/wiki/Bram_Moolenaar