vi、Vim 文字編輯器教學和常用按鍵與指令表

Vim

詳細解說廣泛使用在 Linux 的文字編輯器 vi、Vim 它的模式和各種常用按鍵與指令,還有發生問題如何使用暫存檔來恢復資料,以及 Vim 的額外功能,像是插件 Emmet、關鍵字提示、自動補齊和環境參數設定。

模式

一般指令模式

使用 vi 或 vim 指令開啟檔案的一開始為「一般指令模式」,此模式可以使用以下操作:

  • 移動游標。
  • 刪除、複製、貼上。
  • 復原、重做。
  • 區塊範圍 (選取、複製、貼上)。
  • 多視窗功能。

編輯模式

在「一般指令模式」鍵盤按下 ioar 任一字母可進入「編輯模式」(直到按下鍵盤 Esc 才會退出「編輯模式」),此模式可以使用以下操作:

  • 插入功能:ioa
  • 取代功能:r

「插入功能」畫面:

「取代功能」畫面:

指令列命令模式

在「一般指令模式」鍵盤輸入 /:? 任一個符號,游標就會移到最底下的「指令列命令模式」,此模式可以使用以下操作:

  • 搜尋、取代。
  • 儲存、離開、讀入檔案。
  • 顯示行號、執行 Shell 指令。
  • 多檔案編輯。

按鍵、快速鍵與指令

方向鍵

在「一般指令模式」可以使用鍵盤的方向鍵來移動游標,其實也可以使用鍵盤 hjkl 來代替 (圖片來源 vi - 維基百科,自由的百科全書):

一般指令模式

移動游標

:為常用[N]:為任意數字

按鍵 說明 備註
h 游標向 ← 移動一個字元 先按數字鍵,游標可移動多個字元,例如 2h
j 游標向 ↓ 移動一個字元
k 游標向 ↑ 移動一個字元
l 游標向 → 移動一個字元
Page Down
Ctrl + f
螢幕向 ↓ 滾動一頁
Page Up
Ctrl + b
螢幕向 ↑ 滾動一頁
Ctrl + d 螢幕向 ↓ 滾動半頁
Ctrl + u 螢幕向 ↑ 滾動半頁
+ 游標移動到非空白字元的下一列 按住 Shift= 才是 +
- 游標移動到非空白字元的上一列
[N]Space 游標向後移動 [N] 個字元 Space 為空白鍵
Home0 游標移動到當前列的第 1 個字元
End$ 游標移動到當前列的最後一個字元
H 游標移動到當前螢幕第一列的第一個字元
M 游標移動到當前螢幕中間那一列的第一個字元
L 游標移動到當前螢幕最後一列的第一個字元
G 游標動到檔案的最後一列
[N]G 游標移動到檔案的第 [N]
gg 移動到檔案的第一列
[N]Enter 游標向下移動 [N]

刪除、複製、貼上

:為常用 [N]:為任意數字

按鍵 說明 備註
xDelete 刪除當前游標字元
XBackspace 刪除游標前一個字元 Backspace 需配合環境設定
[N]x 從游標開始刪除 [N] 個字元
dd 刪除游標所在那一整列
[N]dd 從游標那列開始,向下刪除 [N]
d[N]G 從第 [N] 列開始,刪除至游標那一列
dG 從游標列開始,向下刪除至最後一列
dgg 從游標列開始,向上刪除至第一列
d0 從第一個字元開始,刪除至游標前一個字元 0 為數字鍵
d$ 從游標開始,刪除至最後一個字元
yy 複製游標那一列
[N]yy 從游標那列開始,向下複製 [N]
y[N]G 從第 [N] 列開始,複製至游標那一列
yG 從游標列開始,向下複製至最後一列
ygg 從游標列開始,向上複製至第一列
y0 從第一個字元開始,複製至游標前一個字元 0 為數字鍵
y$ 從游標開始,複製至最後一個字元
p 將複製的資料向後貼上
複製整列:在游標下方貼上
複製一段:在游標右邊貼上
P 將複製的資料向前貼上
複製整列:在游標上方貼上
複製一段:在游標左邊貼上
J 將游標那列與下一列結合成同一列 J 為 Join
[N]c[方向鍵] [方向鍵] 指定的方向,刪除指定 [N] 個字元或列
↑↓:從游標列開始,刪除 [N] + 1 列
←:從游標前一個字元,向 ← 刪除 [N] 個字元
→:從游標開始,向 → 刪除 [N] 個字元

復原、重做

:為常用

按鍵 說明
u 復原前一個動作
Ctru + r 重做上一個動作
. 重複前一個動作 (例如刪除、貼上)

區塊範圍 (選取、複製、貼上)

:為常用

按鍵 說明
v 反白選取字元
V 反白選取整列
Ctrl + v 反白選取矩形區塊
y 複製反白處
d 刪除反白處
p 將複製的資料向後貼上
P 將複製的資料向前貼上

多視窗功能

:為常用

指令和按鍵 說明 備註
:split [filename] 將目前視窗水平分割為二,如未指定 [filename] 則開啟當前的檔案 簡寫 :sp
:vsplit [filename] 將目前視窗垂直分割為二,如未指定檔案名稱 [filename],則開啟同一檔案 簡寫 :vsp
:new 將目前視窗水平分割為二,並開啟新檔
:vnew 將目前視窗垂直分割為二,並開啟新檔
Ctrl + ww 移至下一個視窗,到達最後一個則移至第一個視窗
Ctrl + w + [方向鍵] 移至 [方向鍵] 視窗 須先按 Ctrl + w 後放開,再按其它鍵
Ctrl + w + q 結束當前視窗 (同 :q)

編輯模式

插入、取代

:為常用

功能 按鍵 備註
插入 (Insert) i 從游標所在處插入
I 從游標所在列第一個非空白字元處插入
a 從游標所在處的下一個字元插入
A 從游標所在列的最後一個字元處插入
o 在游標下插入新的一列
O 在游標上插入新的一列
取代 (Replace) r 取代游標所在的字元一次
R 永久取代游標所在的字元,直到按下按鍵 Esc 為止
退出 Esc 退出「編輯模式」,回到「一般指令模式」

指令列命令模式

搜尋、取代

:為常用[N] [N1] [N2]:為任意數字

指令和按鍵 說明 備註
/word 向游標以下搜尋內容為 word 的字元
?word 向游標以上搜尋內容為 world 的字元
n 重複搜尋動作 在「一般指令模式」使用
N 反向重複搜尋動作
:[N1],[N2]s/word1/word2/g 從第 [N1] ~ [N2] 列之間搜尋內容為 word1 的字元,並將該字元取代為 word2
:[N],$s/word1/word2/g 從第 [N] ~ 最後一列尋找內容為 word1 的字元,並將該字元取代為 word2
:[N],$s/word1/word2/gc 同上,但在取代前會顯示如下提示字元給使用者確認
eplace with IS (y/n/a/q/l/^E/^Y)?
y (Yes):取代游標選取的字串,並將游標移至下一個匹配的字串。
n (No):不取代游標選取的字串,並將游標移至下一個匹配的字串。
n (No):不取代游標選取的字串,並將游標移至下一個匹配的字串。
q (Quit):離開。
結尾的 c 為 Confirm

儲存、離開、讀入檔案

:為常用 [N1] [N2]:為任意數字

指令和按鍵 說明 備註
:w 儲存檔案 w 為 Write
:w! 若檔案屬性為「唯讀」,須使用此方式來強制儲存檔案 與帳戶有無該檔案的權限有關
:q 離開 q 為 Quit
:q! 若已修改過檔案,但不想儲存,可用此方式強制離開
:wq 同上 :w + :q
:wq! 同上 :w! + :q!
:w [filename] 另存新檔,檔案名稱為 [filename]
:r [filename] 將另一個檔案 [filename] 的資料插入至游標所在的下一列,如未指定 [filename] 則讀入當前的檔案
:[N1],[N2] w [filename] 將第 [N1][N2] 列的資料另存新檔,檔案名稱為 [filename]
ZZ 檔案已更動:不儲存離開
檔案未動過:儲存離開
在「一般指令模式」使用

顯示行號、執行 Shell 指令

:為常用

指令 說明 備註
:! Command 執行 Shell 指令並顯示結果 例如 :! ls /home 可察看檔案資訊
:set nu 是否顯示行號
:set nonu

多檔案編輯

可以使用 vi 或 vim 一次開啟多個檔案,如下一次開啟二個檔案:

vim /etc/passwd /etc/hosts

鍵盤輸入 :files 列出開啟的所有檔案:

  • %a:當前使用的檔案。
  • 行:檔案內的游標停留在第幾行。

鍵盤輸入 :n 切換到下一個檔案,再輸入 :files 列出開啟的所有檔案:

  • #:上一次使用的檔案。

:為常用

指令 說明 備註
:n 切換到下一個檔案
:N 切換到上一個檔案
:files 列出 vim 開啟的所有檔案 vi 不支援

暫存檔、恢復資料

使用 vi 或 vim 編輯檔案時,突然發生斷電或系統當機,但尚未儲存檔案怎麼辦呢!

其實使用 vi 或 vim 開啟檔案時,會自動產生一個對應的暫存檔來同步編輯的資料,當正常離開 vi 或 vim 時暫存檔就會消失,但如果 vi 或 vim 工作被不正常中斷時,這個暫存檔就不會消失了,這時就可利用這個暫存檔來恢復先前編輯過但尚未儲存的資料。

vi 恢復資料的介面不像 vim 那麼友善,因此這裡使用 vim 解說工作被不正常中斷的情況。

先新增 test.txt 檔案,內容為 "123":

echo '123' > test.txt

使用 vim 指令開啟 test.txt 檔案,增加內容 "abc" 但不儲存檔案,直接按下 Ctrl + z 把 vim 丟到背景去執行:

vim test.txt
123
abc

[1]+  Stopped                 vim test.txt

查看檔案會發現多了一個 .test.txt.swp 暫存檔:

ll test.txt .test.txt.swp
-rw-r--r--. 1 root root     4  7月 16 15:43 test.txt
-rw-r--r--. 1 root root 12288  7月 16 15:53 .test.txt.swp

使用 kill 指令模擬系統將 vim 工作刪除的情況,來演練當機的情況:

kill -9 %1

[1]+  Stopped                 vim test.txt
[root@localhost ~]#
[1]+  已砍掉               vim test.txt

再查看檔案確認 .test.txt.swp 暫存檔還在:

ll test.txt .test.txt.swp
-rw-r--r--. 1 root root     4  7月 16 15:43 test.txt
-rw-r--r--. 1 root root 12288  7月 16 15:53 .test.txt.swp

這時再開啟 test.txt 檔案時,系統就會提示找到該檔案的暫存檔,以及發生此問題的原因與應對方式:

vim test.txt

E325: 注意                                              # 錯誤代碼
找到暫存檔 ".test.txt.swp"                              # 找到的暫存檔
            擁有者: root    日期: Mon Jul 16 15:53:15 2018
              檔名: ~root/test.txt                      # 暫存檔屬於哪個實際檔案
            修改過: 是
            使用者: root    主機名稱: localhost.localdomain
        process ID: 1872
在開啟檔案 "test.txt"
              日期: Mon Jul 16 15:43:31 2018            # 可能有另一個程序正在編輯同一份檔案,請他先結束編輯,再重新開啟檔案
(1) Another program may be editing the same file.  If this is the case,
    be careful not to end up with two different instances of the same
    file when making changes.  Quit, or continue with caution.
# 檔案可能有問題但能用暫存檔來恢復,
(2) An edit session for this file crashed.
    如果是這樣, 請用 ":recover" 或 "vim –r test.txt"    # vim 直接使用最底下的按鈕即可,這裡較適用 vi
    來救回修改資料 (詳細說明請看 ":help recovery").
    如果該救的都已經救了, 請直接刪除此暫存檔 ".test.txt.swp"
    以避免再看到此訊息.

暫存檔 ".test.txt.swp" 已經存在了!
[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort:

按鍵說明:

按鍵 說明 備註
[O]pen Read-Only 唯讀方式開啟檔案
(E)dit anyway 正常編輯檔案 (不載入暫存檔內容)
(R)ecover 載入暫存檔來恢復內容 恢復後,儲存離開 vim 須自行刪除此暫存檔
(D)elete it 自動刪除暫存檔後正常編輯檔案
(Q)uit 離開 沒有差別
(A)bort 放棄

vim 額外功能

vim 與 vi 差異

vim 是從 vi 發展出來的一套文字編輯器,而且 vim 有一些較方便的功能:

  • 程式高亮。
  • 相關語法提示。
  • 除錯。

vim 編輯畫面

使用 vim 指令的編輯畫面:

  • /etc/services:開啟的檔案名稱,由於這是系統的設定檔,因此 vim 會進行語法檢驗,而畫面中藍色的文字為 # 註解。
  • [唯讀]:該使用者沒有可編輯該檔的權限。
  • 11176L:該檔案內容有多少列 (L 為 Line)。
  • 670293C:該檔案內容有多少字元 (C 為 Char)。
  • 1, 1:游標位置在第 1 列第 1 個字元。
  • 頂端:目前位置在第一頁 (第二頁之後則使用 % 百分比顯示,最後一頁則顯示底端)。
vim /etc/services

接著將游標移至底端,可以發現關鍵字也會以其它顏色顯示:

插件

Emmet

Emmet 可以使用類似 CSS 選擇器的方式,快速產生 HTML 標籤。

須要安裝 unzip、與 wget 軟體,等等才能下載 Emmet 與解壓縮 zip 檔:

yum install unzip

在家目錄新增 .vim 目錄,並切換至該目錄:

mkdir ~/.vim
cd ~/.vim/

下載 Emmet 插件並更改檔名:

wget https://www.vim.org/scripts/download_script.php?src_id=23483
mv download_script.php\?src_id\=23483 emmet-vim.zip

解壓縮 Emmet 插件,並確認是否有 autoload、plugin 這兩個目錄:

unzip emmet-vim.zip
ls
autoload  doc  emmet-vim.zip  plugin

刪除 Emmet 壓縮檔:

rm emmet-vim.zip
rm:是否移除普通檔案‘emmet-vim.zip’? y

切換到家目錄,就可使用 vim 新增檔案來測試 Emmet 功能:

cd ~
vim index.html

按鍵盤 i 進入「編輯模式」的插入功能,如果要快速產生 html 檔案結構,只要輸入內容 html:5 後按鍵盤 Ctrl + y 放開再按 , 逗號:

如果要快速產生 ul 標籤內含二個 li 子標籤,只要輸入內容 ul>li*2 後按鍵盤 Ctrl + y 放開再按 , 逗號:

關鍵字提示、自動補齊

開啟 .html 檔,嘗試相關聯語法的關鍵字提示:

vim index.html

按鍵盤 i 進入「編輯模式」的插入功能,如下位置輸入 b 後按鍵盤 Ctrl + x 放開再按 Ctrl + o

相關功能表:

:為常用

按鍵 說明 備註
Ctrl + x Ctrl + o 相關聯語法關鍵字補齊 產生的語法會與副檔名有關,例如 .html .php
Ctrl + n 檔案內容相關聯的關鍵字補齊
Ctrl + f 當前目錄內檔名相關聯的關鍵字補齊

環境參數設定

如果要讓 vim 開啟檔案一開始就顯示行號,或者按鍵盤 Tab 能變成四個空白鍵,這時就可透過 vim 的環境設定,可以透過以下的檔案達成:

  • 整體設定檔:/etc/vimrc (不建議修改)
  • 個人設定檔:~/.vimrc (預設不存在,須手動建立)

新增 vim 的個人設定檔,並依需求將相關參數加入 vim 的個人設定檔,下述為腳印哥常用設定:

vim ~/.vimrc
set autoindent
set bg=dark
set nu
set shiftwidth=4
set tabstop=4

參考表:

:為常用 [N]:為任意數字

參數 預設 說明 備註
set autoindent 換行是否自動縮排
set noautoindent
set bg=dark 背景顏色較暗文字較亮 如果註解的藍色字看不清楚,可設定 dark
set bg=light 背景顏色較亮文字較暗
set hlsearch 搜尋到的字串是否反白 hl 為 high light
set nohlearch
set nu 是否顯示行號
set nonu
set shiftwidth=[N] 程式產生的縮排使用幾個空白鍵 例如 Emmet 插件,自動產生的程式
通常同 set tabstop 設定
set tabstop=[N] Tab 使用幾個空白鍵 通常設定 4
syntax on 依相關語法顯示不同顏色
syntax off

實用技巧

多行插入

假設有一份檔案,它的月份都是 1 ~ 9 月,而要在所有月份的前面加上數字 0。

首先游標停在第一列的月份:

按鍵盤組合 Ctrl + v 選取矩形區塊,再按鍵盤 到最底:

按鍵盤組合 Shift + i

輸入要新增的數字 0:

最後按鍵盤 Esc,約 1 秒就會看見剛才選取的矩形區塊都插入數字 0 了:

參考

在〈vi、Vim 文字編輯器教學和常用按鍵與指令表〉中有 1 則留言

發表留言