Linux深入探索03-文本編輯vi/vim

----- 最近更新【2022-01-26】-----

本文目錄結構預覽:

  • 一、簡介
  • 二、存儲原理
  • 三、使用 vim
    1、語法
    2、vim的模式
  • 四、命令模式
    1、移動光標
    2、搜索
    3、使用行號
    4、替換文本
    5、刪除與撤銷
    6、復制與粘貼
    7、換行
    8、設置選項
    9、使用shell命令
    10、插入文件中的數據
    11、保存與退出
  • 五、異常恢復
  • 六、初始化文件
  • 七、總結
  • 八、參考

一、簡介

Unix系統的文本編輯器有許多種(vi、vim、nano、emacs等),但本文只討論vi/vim,因為vi/vim是Unix系統上最常用的文本編輯器。絕大部分Unix系統都默認安裝有vi或者vim程序,或者二者同時安裝。

其實vim就是vi的改進版,而且現在很多Linux系統都用vim取代了vi,但是同時又保留了vi這個命令的使用習慣。意思就是,在你的系統上vi和vim命令都可以使用,但其實你使用的是同一個程序,因為vi指向的也是vim。

用下面的方法你可以證明你使用的vi是不是vim:

linux1@noseeu:~$ which vi
/usr/bin/vi
linux1@noseeu:~$ which vim
/usr/bin/vim
linux1@noseeu:~$ ls -l /usr/bin/vi*
lrwxrwxrwx 1 root root      20 Feb  1  2021 /usr/bin/vi -> /etc/alternatives/vi
lrwxrwxrwx 1 root root      21 Feb  1  2021 /usr/bin/vim -> /etc/alternatives/vim
-rwxr-xr-x 1 root root 3165768 Nov  8 14:21 /usr/bin/vim.basic
linux1@noseeu:~$ ls -l /etc/alternatives/vi*
lrwxrwxrwx 1 root root 18 Feb  1  2021 /etc/alternatives/vi -> /usr/bin/vim.basic
lrwxrwxrwx 1 root root 18 Feb  1  2021 /etc/alternatives/vim -> /usr/bin/vim.basic
linux1@noseeu:~$ 

或者你直接在命令行輸入vi也可以知道。

這兩者的使用方法其實基本是一樣的,本文將以vim為環境展開介紹。

二、存儲原理

當使用vim時,存放數據的存儲區域稱為編輯緩沖區(editing buffer)。當使用vim編輯文件時,vim就將文件的內容復制到編輯緩沖區,因此你處理的內容其實是數據的副本,而不是原始數據。

vim通過將編輯緩沖區保存在一個交換文件(swap file)中,提供了出色的恢復功能,交換文件與正在編輯的文件存儲在同一個目錄中。交換文件的名稱一般是.原文件名.swp這樣的格式。

三、使用 vim

1、語法

vim - Vi IMproved, a programmer's text editor.

vim [options] [file ..]
vim [options] -
vim [options] -t tag
vim [options] -q [errorfile]

vim 命令的選項非常多,但是大多時候我們并不需要用到,我們最常用的只是“vim [文件名]”。

一般情況下,我們還需要知道的是這兩個選項:-r(恢復文件)和 -R(只讀模式),后面會詳細介紹。

對于習慣使用 vi 的同學,可以使用vim -C來啟動 vim,這個選項可以使 vim 盡可能地像 vi 一樣。

2、vim的模式

vim有兩種模式:命令模式(command mode)和輸入模式(input mode)。

1)在命令模式時,所有鍵入的鍵都會被解釋成命令。
當啟動vim時,你所處在的模式就是命令模式。
可以使用這些命令切換到輸入模式:i、a、I、A、o、O。當然,這6種并不是所有切換到輸入模式的方式,它們是比較常用的方式。

命令 說明
i (insert) 切換到輸入模式:在當前光標位置前插入數據
a (append) 切換到輸入模式:在當前光標位置后插入數據
I 切換到輸入模式:在當前行開頭處插入數據
A 切換到輸入模式:在當前行末尾處插入數據
o (open) 切換到輸入模式:在當前行下面插入一行
O 切換到輸入模式:在當前行上面插入一行

2)在輸入模式時,鍵入的內容將直接插入到編輯緩沖區。
在輸入模式時按<Esc>鍵就可以切換到命令模式。當你不知道自己是處于什么輸入模式時,只需要連續按兩次<Esc>鍵就可以確保你是在命令模式了。

當你處于輸入模式時,Vim將在屏幕下方顯示如下提醒:

-- INSERT --  

下面將著重介紹命令模式下的常用操作。

四、命令模式

1、移動光標

按鍵 說明
← / <Backspace> 將光標向左移動一個位置
→ / <Space>(空格鍵) 將光標向右移動一個位置
將光標向上移動一個位置
將光標向下移動一個位置
<Enter> 將光標移動到下一行的開頭
0(數字0) / <Home> 將光標移動到當前行的開頭
$ / <End> 將光標移動到當前行的末尾
^ 將光標移動到當前行第一個非空字符上
w 將光標移動到下一個單詞的詞首
e 將光標移動到下一個單詞的詞尾
b 將光標移動到上一個單詞的詞首
) 向前移動到下一個句子
( 向前移動到上一個句子
} 向前移動到下一個段落
{ 向前移動到下一個段落
H 將光標移動到屏幕的頂部(high)
M 將光標移動到屏幕的中間(middle)
L 將光標移動到屏幕的底部(low)
<Ctrl>-F / <PageDown> 向下(前)移動一屏
<Ctrl>-B / <PageUp> 向上(后)移動一屏
`` 將光標返回上一個位置

為了增強移動命令的功能,可以通過在命令前面輸入一個數字來重復執行光標移動命令。如:向下移動10行“10↓”,或者向前移動5個單詞“5w”。通常對于任何vim命令使用重復數次都是允許的,只要這樣做有意義。

2、搜索

命令 說明
/ 向下搜索一個匹配值
? 向上搜索一個匹配值

如你要搜索單詞was,則可鍵入“/was”,然后按<Enter>鍵。系統就會從你光標的位置開始向下搜索,然后跳到第一個搜索到的位置。

你需要繼續搜索的話,則可以按n鍵,將延相同方向繼續搜索(/模式繼續向下搜索,?模式繼續向上搜索),按N鍵則延相反方向搜索。

為了更加的靈活,vim允許使用正則表達式指定搜索內容。如:輸入/R[a-z]*d然后回車。

3、使用行號

顯示行號::set number
隱藏行號::set nonumber

跳到指定行號,如跳轉到第50行:50G,注意G是大寫。
跳到文本的第一行:gg,連續按兩次g鍵,相當于1G
跳到文本的最后一行:G,大寫G。

也可以通過鍵入:后面跟行號,再按回車跳轉到指定行。
如跳到200行::200
跳到文本末尾::$,等同于G

4、替換文本

命令 說明
r 可以將一個字符替換為另一個字符
:s/pattern/replace/ 替換當前行
:lines/pattern/replace/ 替換指定行,line表示行號
:line,lines/pattern/replace/ 替換指定范圍的行
:%s/pattern/replace/ 替換所有行
~ 使用~鍵,可以使用當前光標處的字符進行大小寫切換

pattern是希望被替換掉的模式,replace是替換文本。

在命令行的末尾,可以使用c告訴vim在替換前需要再次確認,而使用g則表示替換該行的所有匹配項。
當進行多條替換并未結束的時候,可以通過按<Ctrl>-C來中途停止,這將放棄整條命令的替換。

如:
:%s/UNIX/Linux/g表示把全文的UNIX替換為Linux。
:.,$s/UNIX/Linux/g表示從當前行到最后一行的UNIX替換為Linux,.(點號)代表當前行,$代表最后一行。

5、刪除與撤銷

刪除:

命令 說明
x 刪除當前光標處的字符
X 刪除光標左邊的字符
D 刪除從當前光標到本行末尾的字符
dd 刪除當前行(dd前面也可以加數字,如10dd從當前行開始往下刪除共10行)
:lined 刪除當前行,line表示行數,如::5d刪除第5行,:%d刪除全部
:line,lined 刪除指定范圍的行,如:1,.d將第一行到當前行之間的所有行刪除,:1,$d刪除全部

d后面還可以跟一條光標移動命令,這時將刪除從當前光標位置到光標移動命令所指示位置的所有字符。
如:
dw,刪除一個單詞
d10w,刪除10個單詞
db,向后刪除一個單詞
d2),刪除2個句子
dgg,刪除當前行到第一行的所有內容

撤銷:

命令 說明
u 撤銷上一命令的修改內容
U 恢復當前行
. 重復上一命令的修改

U命令可以將撤銷自移動到當前行的那一刻起,對當前行所進行的所有改變。U命令可以撤銷大量改變,一次就將當前行的所有改變都恢復。但是,僅當沒有離開這一行時U命令才有效。

使用.命令的時候要特別小心。當你使用u命令撤銷一個修改時,點擊一次.將取消你剛剛的撤銷。
.命令的詳細介紹是:重復上一命令對編輯緩沖區的修改。
比如:你在文本某個位置插入了一個單詞(添加了一個單詞),然后你不想要這個單詞了,你可以按u撤銷剛剛插入的單詞(單詞被刪了)。但突然你又想要了,你就可以按.來取消剛剛的撤回(單詞又回來了)。但這時你再按一次.的話,那剛剛恢復的單詞會再恢復一次(這一般不是你要的結果)。
再比如:當你用dd刪除一行文本后,按.你會發現也會繼續再刪除一行文本,這時你繼續按.它還會繼續刪。

6、復制與粘貼

vim總是在一個稱為無名緩沖區(unnamed buffer)的儲存區中為上一次刪除(或者復制)保存一份副本。在任何時候,都可以使用p和P(put 放入)命令將無名緩沖區的內容復制到編輯緩沖區中。注意,無名緩沖區每次只能存放一次內容,也就是最新的一次。

p(小寫)命令將無名緩沖區的內容插入到光標當前位置之后。如果無名緩沖區的內容是整行的話,那么p命令會將無名緩沖區中的行插入到當前行的下面。
P(大寫)命令將無名緩沖區的內容插入到光標當前位置的左邊。如果無名緩沖區的內容是整行的話,那么p命令會將無名緩沖區中的行插入到當前行的上面。

刪除命令前面已經介紹過了,那么怎么把內容復制到無名緩沖區呢?

在不刪除文本的情況下,可以使用y、yy和Y命令將文本復制到無名緩沖區中,我們稱這是接出(yank)了文本。

常用操作組合:

命令 說明
p 把無名緩沖區的內容,插入到光標后面/下面
P 把無名緩沖區的內容,插入到光標前面/上面
xp 調換兩個字符的位置
deep 調換兩個單詞的位置
ddp 調換兩個行的位置
yw 接出(復制)1個單詞
y10W 接出(復制)10個單詞(忽略標點符號)
yy 接出(復制)1整行
10yy 接出(復制)10整行
Y 可以用Y(大寫)來代替yy

除了上面常用的復制粘貼命令,當我們遇到大量的行需要進行復制粘貼時,可以使用下面的方法:
:co(copy,復制)與:m(move,移動)。其中:co不刪除原始行,:m刪除原始行。

命令 說明
:x[,y]coz 把x(或者x至y)行復制到z行的下面
:x[,y]mz 把x(或者x至y)行移動到z行的下面

上面的x、y和z都表示行號。

7、換行

1)換行

命令 說明
r 可以將一個字符替換為另一個字符

所以當鍵入r然后<Enter>回車,就變成換行了。

2)合并行
把光標移動到某一行,然后鍵入J(大寫字母“j”),這將會把當前行與下一行合并成一行。
J的前面也可以加數字,如5J合并5行(把當前行與它下面的4行合并)。

8、設置選項

前面的第3小節【3、使用行號】用的就是vim中設置選項的語法:set number

設置選項的命令語法有以下兩種形式:

:set [no]option...
:set option[=value]...

:set option表示打開某項設置,:set nooption表示關閉某項設置,vim中很多設置選項默認值都為off(關閉狀態)。

常用設置選項:

命令 縮寫 默認值 說明
:set number:set nonumber :set nu:set nonu off 顯示行號、(默認)隱藏行號
:set tabstop=num ts 8 設置制表符的間距(默認一般為8)
:set ignorecase ic off 在搜索過程中忽略大小寫(默認不忽略)
:set list off 將制表符顯示為^I,將行的結束顯示為$
:set lines=num 24 屏幕顯示文本的行數(窗口/屏幕大小-1)
:set shiftwidth=num sw 8 aotoindent(自動縮進)使用的空格數量
:set all 查看所有選項的值(這個挺有用的)
:set :set命令本身可以查看那些改變了默認值的選項
:set option? 在指定選項后面加?(問號)可以查看該選項的值,如::set number?
:set wrapmargin=num wm 0 該選項只影響輸入模式,表示vim編輯時輸入的行內容離右邊緣num個字符數時自動換行,0表示不自動換行

設置選項的語法允許多個選項同時設置,如::set number tabstop=4

9、使用shell命令

在vim中有幾種調用常規shell的方法。

命令 說明
:!command :!command表示:!+shell命令。暫停vim,執行shell命令
:!! 暫停vim,執行上一條shell命令
:sh:!bash 暫停vim,啟動一個新shell
:r!command:r !command 在vim的編輯緩沖區插入shell命令的輸出內容,r后面可以加一個空格

如:
:!date,將暫時退出vim執行date命令,執行完date命令后再按<Enter>按就可以回到vim了。
:r!date,將在你的光標處的下一行插入date命令的輸出內容。

:sh:!bash命令可以暫時退出vim回到shell界面,這時你可以在shell界面執行多條shell命令。執行結束之后可以按<Ctrl>-D或者加入exit就可以回到vim。

與下面小節介紹的一樣:r可以加入行號。

10、插入文件中的數據

在vim中,想把現有的文本插入當前的編輯緩沖區,可以使用:r命令,語法如下:

命令 說明
:[line]r filename line是行號,filename是文件的名稱

:r命令讀取文件filename的內容,并將該內容插入到編輯緩沖區的指定行之后。如果末指定line則表示插入到當前行之后。

如:
:0r test.txt表示把test.txt文件的內容插入到編輯緩沖區的開頭。
:$r test.txt表示把test.txt文件的內容插入到編輯緩沖區的末尾。

11、保存與退出

命令 說明
:w write,將數據寫入到原始文件,即保存文件
:w filename 將數據寫入到一個新文件
:w! filename 覆蓋一個已有的文件
:w>>filename 將數據追加到指定文件中
ZZ:wqx <Shift>-z-z ,保存文本并退出vim
:!q 強制退出,不保存修改

如果忘記了正在編輯哪個文件,可以按<Ctrl>-G,這將顯示文件名稱和你在這個文件中的位置。

在自用vim編輯文件的時,當你完成了當前文本的工作,使用以下命令可以不需要退出vim直接打開新的文件。

命令 說明
:e filename 切換到一個新文件
:e! 重新打開原文件

使用該命令要確保當前文本已經用:w命令保存了,否則vim會彈出一個錯誤提示。當然,不需要保存的話你也可以用:e! filename命令強制切換。

當你對當前文件做了很多更改時,突然全都不想要了,那你可以用:e!命令重新打開原始文件。

五、異常恢復

當你在使用vim編輯文件的時候,突然程序意外中斷了(如斷電、斷網、程序崩潰、人為失誤等),這時怎么辦。

放心,vim也提供了非常出色的恢復功能。前面也有介紹,當你在使用vim編輯文件時,vim將文件的內容保存到一個編輯緩沖區中,就是一個交換文件(swap file),名稱一般是.原文件名.swp這樣的格式。

當你正常保存退出vim后,這個交換文件會被自動退出。但是當你是意外中斷編輯的時候,該文件不會被自己刪除,這時你會可以用它來恢復你的數據了。

這里我可以模擬一下,在我編輯文件testmini時,由于斷網意外與服務器連接突然中斷了,我修改的內容也沒保存。

這回我重新登錄系統時,可以看到如下:

linux1@noseeu:~$ ll
-rw-rw-r-- 1 linux1 linux1  1162 Dec 22 18:07 testmini
-rw-r--r-- 1 linux1 linux1 12288 Dec 22 18:07 .testmini.swp
linux1@noseeu:~$ 

或者使用命令vim -r去查看可恢復文件。

此時,文件夾中多了一個文件.testmini.swp,接下來我可以用如下方法進行恢復:

方法1:直接用vim打開原始文件,然后根據提示操作。

當我用vim testmini直接打開時可以看到如上的提示。vim給我們提供了5個選項:

命令 說明
[O]pen Read-Only 以只讀模式打開(打開的是編輯前的原文件)
(E)dit anyway 繼續編輯(也是打開編輯前的原文件)
(R)ecover 恢復 (把異常中斷的數據恢復,然后打開編輯)
(Q)uit、 (A)bort 退出(不進行任何操作)

從上表可以看出,到這里我們按R(這里不區分大小寫)鍵然后回車,就可以恢復我們編輯的數據。(之后記得要保存再退出)

方法2:使用命令vim -r filename

linux1@noseeu:~$ vim -r testmini 

這時提示如下:

這時直接按回車就行(然后保存、退出)。

最后!不管你是通過以上兩種方法中的哪一種來恢復數據,還有最后一步就是你都得手動刪除.原文件名.swp這個文件。

linux1@noseeu:~$ rm .testmini.swp 

否則你每次用vim打開這個文件的時候它都會彈出提示。

六、初始化文件

在vim啟動時,它會在home目錄中查找初始化文件。如果存在初始化文件,vim會讀取并執行查找到的初始命令。

vim首先會查找.vimrc(rc, run commands)文件,如果該文件不存在,那么繼續查找.exrc(ex, vi的早期版本)。如果兩個文件都同時存在,vim只會讀取.vimrc文件。

其時,vim的初始化文件可以非常簡單,一般就是經常使用的一些set命令。如下是我創建的一個.vimrc文件:

七、總結

本文的內容包括了vim的絕大部分常用操作和命令,希望能夠幫助到大家。

其實,這只是vim的冰山一角,vim的功能是如此的強大和復雜,以至于可以說“沒有一個人能知道vim的所有內容”,事實上也沒有這個必要。

如果覺得本文沒有能滿足你的胃口,想要去了解更多,那么你也可以去查看vim的其它相關教程。在linux系統可以直接使用命令vimtutor查看《VIM Tutor》,打開看到的頁面將會如下:

《VIM Tutor》總共分為七大課時,每個課時包含若干小節,然后每個課時最后都會附帶一篇總結,也是一篇不錯的教程。

最后,這里總結幾個大家可能會感興趣的vim的其他功能,方便大家想了解的時候可以去查找:

  • 分屏操作 Split
  • 折疊操作 Folding
  • 語法高亮 Syntax Highlighting
  • 視圖模式 Visual mode
  • 內置腳本 Vim script
  • 宏 Macro

我試了一下分屏、折疊這兩個功能,感覺還挺好玩的,哈哈哈......

分屏、折疊的效果圖:

最后,最后

花了兩天兩夜的時間,終于把關于vim的知識點整理完了。有哪里寫錯的,或寫得不好的地方,歡迎大家批評指正。

八、參考

VIM User Manual:https://vimhelp.org/usr_toc.txt.html (更全面!)
書箱:《Unix & Linux 大學教程》第二十二章 (美)Harley Hahn 著 張杰良 譯
教程:《 VIM Tutor — Version 1.7》 Michael C. Pierce、Robert K. Ware

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,546評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,570評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,505評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,017評論 1 313
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,786評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,219評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,287評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,438評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,971評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,796評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,995評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,540評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,230評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,918評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,697評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,991評論 2 374

推薦閱讀更多精彩內容