Vim 命令大全:常用命令速查表與維運必會 20 條
Vim 命令大多在普通模式下執行,格式是“次數 + 操作 + 範圍”:dd 刪一行,3dd 刪三行,dw 刪到下一個詞。下面按移動、插入、刪除、複製貼上、查詢替換、儲存退出分組列出,標 ★ 的 20 條足夠完成日常改配置的工作。
Vim 命令分兩類:一類是在普通模式下直接按的鍵,如 dd、yy、p;另一類是按冒號後在螢幕底行輸入、回車執行的命令,如 :wq、:%s/舊/新/g。下面的速查表按用途分成六組,每條附一句說明,標 ★ 的 20 條是維運修改配置檔案時用得最多的,先把它們練熟,其餘的用到再查。除特別註明的以外,表中命令都在普通模式下執行;不確定當前處於哪個模式,先按 Esc。
先看懂組合規則:次數 + 操作 + 範圍
Vim 的編輯命令大多可以拆成三段,理解了規則,很多命令不用死記:
| 組成部分 | 常見寫法 | 說明 |
|---|---|---|
| 次數 | 3、10 |
寫在最前面,表示重複幾次,省略就是 1 次 |
| 運算子 | d 刪除、c 修改、y 複製、> 右縮排、< 左縮排 |
單獨按不會生效,等你給出範圍 |
| 範圍(移動) | w 下一個詞首、e 詞尾、$ 行尾、0 行首、G 檔案末尾、gg 檔案開頭 |
所有移動游標的命令都能當範圍用 |
| 範圍(文字物件) | iw 一個詞、i" 引號裡面、i{ 花括號裡面、ip 一段 |
游標在物件內任意位置都能用;i 不含邊界,a 連邊界一起 |
照這個規則組合:d$ 刪到行尾,c0 改到行首,dG 從當前行刪到檔案末尾,y3w 複製三個詞,di{ 清空一對花括號裡的內容(改 nginx 的 server 塊很順手),ci" 改寫引號裡的內容。運算子連按兩次表示作用於整行:dd、cc、yy、>>。還有一個省事的 .,它重複上一次修改:在一處把 # 刪掉後,用 n 跳到下一個匹配,再按 . 就完成同樣的修改。
移動游標
| 命令 | 說明 |
|---|---|
h j k l |
左、下、上、右,方向鍵也可以 |
w / b / e |
下一個詞的開頭、上一個詞的開頭、當前詞的結尾 |
★ 0 / $ |
行首、行尾;^ 跳到行首第一個非空字元 |
★ gg / G |
檔案第一行、最後一行 |
★ :行號 |
跳到指定行,如 :120;普通模式下輸入 120G 效果相同 |
★ :set nu |
顯示行號,:set nonu 關閉,配合按行號跳轉和指定範圍 |
Ctrl+f / Ctrl+b |
向下、向上翻一頁 |
Ctrl+d / Ctrl+u |
向下、向上翻半頁 |
H / M / L |
跳到當前螢幕的頂部、中間、底部 |
% |
在配對的 ()、[]、{} 之間來回跳 |
fx / ; |
跳到本行下一個字元 x,; 繼續找下一個 |
g; |
回到上一次修改的位置 |
Ctrl+o / Ctrl+i |
回到跳轉前的位置 / 再跳回來 |
插入、刪除與撤銷
進入插入模式
| 命令 | 說明 |
|---|---|
★ i |
在游標前插入 |
a |
在游標後插入 |
I |
在行首第一個非空字元前插入 |
★ A |
在行尾追加,給配置項補引數時常用 |
★ o |
在當前行下方新開一行並插入 |
O |
在當前行上方新開一行並插入 |
s |
刪除游標處的字元後插入 |
S 或 cc |
清空當前行後插入 |
★ Esc |
回到普通模式,Ctrl+[ 效果相同 |
Ctrl+w(插入模式下) |
刪除游標前的一個詞 |
Ctrl+u(插入模式下) |
刪除本行游標前輸入的內容 |
刪除、修改與撤銷
| 命令 | 說明 |
|---|---|
★ x |
刪除游標處的一個字元,去掉行首的註釋符 # 就靠它 |
★ dd |
刪除整行,5dd 刪除 5 行;刪掉的內容可以用 p 貼上,相當於剪下 |
dw / D |
刪除到下一個詞首 / 刪除到行尾(同 d$) |
dG / dgg |
刪除到檔案末尾 / 刪除到檔案開頭 |
★ cw |
改寫從游標到詞尾的內容,改連接埠號、改引數值常用;游標要先放在詞首,否則只改後半截 |
C |
改寫從游標到行尾的內容 |
r + 字元 |
把游標處的一個字元替換掉,例如 r1 |
R |
進入替換模式,輸入的內容逐個覆蓋原字元 |
J |
把下一行接到當前行末尾 |
~ |
切換游標處字母的大小寫 |
★ u |
撤銷上一步,可以連續撤銷 |
★ Ctrl+r |
重做被撤銷的操作 |
. |
重複上一次修改 |
:e! |
放棄所有未儲存的修改,從磁碟重新載入檔案 |
複製與貼上
| 命令 | 說明 |
|---|---|
★ yy |
複製當前行,3yy 複製 3 行 |
yw / y$ |
複製到下一個詞首 / 複製到行尾 |
★ p / P |
貼上到游標後 / 游標前;複製的是整行時,分別貼上到下一行 / 上一行 |
v、V、Ctrl+v 後按 y |
按字元、按行、按列選中後複製 |
ddp |
當前行與下一行互換位置 |
"ayy / "ap |
複製到名為 a 的暫存器 / 從暫存器 a 貼上,可以同時存好幾段內容 |
:reg |
檢視所有暫存器裡的內容 |
:10,20t 30 |
把第 10 到 20 行復制到第 30 行下方 |
:10,20m 30 |
把第 10 到 20 行移動到第 30 行下方 |
從本機複製一段配置,在終端裡貼上進 Vim,有時每一行都比上一行多縮排一截,或者註釋符號被自動帶到下一行。這是 Vim 把貼上當成了逐鍵輸入,觸發了自動縮排和自動註釋。Vim 從 8.0.0210 補丁起支援“括號貼上模式”(bracketed paste),在支援它的終端裡能自動識別貼上;版本較老、或者經由瀏覽器控制檯把剪貼簿內容模擬成鍵盤輸入時(例如 IPMI 遠端管理裡的 VNC 控制檯貼上),仍可能出現,處理方法是:
:set paste
" 然後按 i 進入插入模式貼上,完成後按 Esc
:set nopaste
查詢與替換
| 命令 | 說明 |
|---|---|
★ /關鍵詞 |
向下查詢,回車後 n 跳到下一個、N 跳到上一個 |
?關鍵詞 |
向上查詢 |
* / # |
查詢游標所在的這個詞,向下 / 向上 |
:noh |
取消查詢結果的高亮 |
/\<listen\> |
只匹配完整的詞,不匹配 listener |
/^#\?Port |
查詢以 Port 或 #Port 開頭的行 |
★ :%s/舊/新/g |
全文替換,% 表示所有行,g 表示一行內的每一處 |
:%s/舊/新/gc |
全文替換,每一處先確認:y 替換、n 跳過、a 剩餘全部替換、q 停止 |
:10,20s/舊/新/g |
只替換第 10 到 20 行 |
:'<,'>s/舊/新/g |
只替換可視模式選中的行,選中後按 : 會自動帶出字首 |
:%s#/var/www#/data/www#g |
內容裡有 / 時,改用 # 作分隔符,免去逐個轉義 |
:%s/\s\+$//e |
刪除所有行尾空格,e 表示沒找到時不報錯 |
:g/關鍵詞/d |
刪除所有包含關鍵詞的行 |
:v/關鍵詞/d |
刪除所有不包含關鍵詞的行 |
Vim 的正則和 grep -E 不完全一樣:+、?、|、() 預設要加反斜槓,寫成 \+、\?、\|、\(\)。表示式複雜時在開頭加 \v(very magic 模式),這些符號就可以直接寫,例如 :%s/\v(\d+)\.(\d+)/\2.\1/g 把形如 1.2 的數字前後對調。
儲存與退出
| 命令 | 說明 |
|---|---|
★ :w |
儲存但不退出,改完先存一下,切到另一個終端裡測試配置 |
★ :wq 或 :x |
儲存並退出;:x 只在內容有改動時才寫檔案,不會白白更新修改時間 |
ZZ |
普通模式下的快捷鍵,同 :x |
★ :q! |
不儲存,強制退出 |
ZQ |
普通模式下的快捷鍵,同 :q! |
:q |
退出;有未儲存的修改時會被拒絕 |
:w 新檔名 |
另存一份,當前編輯的仍是原檔案 |
:sav 新檔名 |
另存為,之後編輯的是新檔案 |
:10,20w 片段.txt |
只把第 10 到 20 行寫到另一個檔案 |
:wa / :qa / :wqa |
開啟多個檔案或分屏時:全部儲存 / 全部退出 / 全部儲存並退出 |
維運常用組合
上面的命令組合起來,能解決改配置時的很多具體麻煩:
| 要做的事 | 操作 |
|---|---|
| 批次註釋連續幾行 | Ctrl+v 進入列選擇,j 向下選中這幾行的行首,按 I 輸入 #,再按 Esc,每行都加上了 |
| 批次取消註釋 | Ctrl+v 選中行首那一列 #,按 x 刪除;也可以用 :20,30s/^#// |
| 只看配置裡生效的行 | vim -R 唯讀開啟,先執行 :g/^\s*#/d 刪掉註釋行,再執行 :g/^\s*$/d 刪掉空行,看完 :q! 退出,原檔案不受影響 |
指令碼報 /bin/bash^M: bad interpreter |
檔案在 Windows 上編輯過,行尾多了回車符。:set ff? 顯示 fileformat=dos 時,執行 :set ff=unix 再 :wq |
| 中文顯示亂碼 | :e ++enc=gb18030 按 GB18030 重新開啟;確認正常後 :set fenc=utf-8 再 :w,檔案就轉成了 UTF-8 |
| 看清 Tab 和行尾空格 | :set list,Tab 顯示為 ^I,行尾顯示 $;YAML 報縮排錯誤時先看這個 |
| 對比兩份配置 | 在 shell 裡執行 vimdiff a.conf b.conf,]c / [c 跳到下一處 / 上一處差異,do 取對方的內容,dp 把這邊的內容推過去 |
| 同時開啟多個檔案 | :e 檔案 切換編輯,:sp 檔案 上下分屏,:vsp 檔案 左右分屏,Ctrl+w w 在視窗間切換 |
| 插入命令的輸出 | :r !date +%F 在下一行插入當天日期,寫變更註釋時用 |
幾點提醒:批次註釋用的列選擇插入,要在按 Esc 之後才會同步到所有選中的行,輸入時只看到第一行有變化是正常的;:g 和 :v 刪除的範圍大,執行前確認自己沒有誤開在需要保留的檔案上,誤刪了馬上按 u;改配置前先用 cp -a 備份一份,比任何撤銷命令都可靠。
常見問題
怎麼在 Vim 裡執行 shell 命令而不退出?
普通模式下輸入 :!命令,例如 :!nginx -t,看完結果按回車回到編輯介面;:r !命令 會把命令輸出插入到游標下方,例如 :r !hostname -I。想臨時回到終端做別的事,按 Ctrl+z 把 Vim 掛到後台,處理完輸入 fg 回來。
這些命令在 vi、vim-tiny、BusyBox vi 裡都能用嗎?
移動、插入、刪除、複製貼上、查詢、:s 替換和儲存退出這些基礎命令都能用。可視模式、多級撤銷、分屏、文字物件屬於 Vim 的擴充套件,精簡版本里可能沒有或不完整,遇到不認的命令就退回基礎寫法。
Vim 裡複製的內容能貼上到電腦上嗎?
預設不能。yy、p 用的是 Vim 自己的暫存器,和作業系統的剪貼簿不通;寫入系統剪貼簿要求 Vim 編譯時帶有 clipboard 功能並且有圖形環境,透過 SSH 連線的伺服器一般不滿足。從 Vim 往外複製,直接用終端軟體的滑鼠選中複製即可。