vim(及它的前辈 vi)是 Linux 服务器上最常见的终端文本编辑器,几乎每个发行版都预装或一条命令就能装上。它最大的特点是键盘驱动:手指不用离开键盘就能完成移动、删除、复制、查找、替换、保存等所有操作。本文按「模式 → 移动 → 编辑 → 查找 → 替换 → 全选 → 保存」的顺序整理一份完整速查,所有命令均在 Ubuntu vim 9.1 实测验证。
💡 先搞懂核心概念——模式:vim 不是像 nano 那样一直打字就有字。它有四种模式:
模式 干什么用 怎么进入 普通模式(Normal) 移动光标、删除、复制等,vim 打开文件后的默认状态 按 Esc插入模式(Insert) 像普通编辑器一样打字 i/a/o等可视模式(Visual) 选中一块文本(相当于鼠标拖选) v/V/Ctrl+V命令行模式(Command-line) 输入 :w保存、:q退出、:s替换等:绝大多数教程的命令都要求在普通模式下按,打字要先进插入模式。卡住了就按
Esc回普通模式,永远安全。
一、打开与退出
1. 打开文件
vim 文件名 # 普通打开,光标在文件开头
vim +10 文件名 # 打开后直接跳到第 10 行
vim +/pattern 文件名 # 打开后直接跳到第一个匹配 pattern 的位置2. 退出与保存
| 命令 | 功能 |
|---|---|
:q | 退出(有未保存修改会报错:E37: No write since last change) |
:q! | 强制退出,不保存(丢弃所有修改) |
:w | 保存 |
:wq | 保存并退出(等价于 :x 和普通模式的 ZZ) |
:wq! | 强制保存并退出(比如只读文件时) |
ZQ | 不保存直接退出(等价于 :q!) |
:e 文件名 | 打开另一个文件(当前文件有修改会拒绝,先保存或用 :e!) |
:set number | 显示行号(写进 ~/.vimrc 永久生效) |
⚠️ 报错原文:退出时报
E37: No write since last change (add ! to override)说明有修改没保存。想保存就:wq,不想要修改就:q!。后面加!就是"强制"的意思。
二、光标移动(普通模式)
| 按键 | 功能 |
|---|---|
h j k l | 左 / 下 / 上 / 右(比方向键快) |
w b e | 下一个词首 / 上一个词首 / 下一个词尾 |
0 ^ $ | 行首 / 行首第一个非空字符 / 行尾 |
gg G | 文件第一行 / 文件最后一行 |
Ngg 或 :N | 跳到第 N 行(如 15gg、:15) |
Ctrl+D Ctrl+U | 向下翻半屏 / 向上翻半屏 |
Ctrl+F Ctrl+B | 向下翻一屏 / 向上翻一屏 |
% | 在成对的 () {} [] 之间跳转 |
H M L | 跳到屏幕顶 / 屏幕中 / 屏幕底 |
{ } | 跳到上一段 / 下一段(按空行分段) |
💡 常用移动组合:
gg回文件头、G去文件尾,配合d、y可以"从这删到文件头/尾"。
三、进入插入模式
| 按键 | 功能 |
|---|---|
i | 在光标前插入 |
I | 在行首插入 |
a | 在光标后插入 |
A | 在行尾插入(最常用) |
o | 在下方新建一行并进入插入 |
O | 在上方新建一行并进入插入 |
s | 删除光标所在字符并进入插入(S 删除整行) |
cw | 删除光标到词尾并进入插入(改词神器) |
cc | 删除整行并进入插入(等价 S) |
C | 删除光标到行尾并进入插入 |
gi | 回到上次编辑的位置进入插入模式 |
Esc | 回到普通模式 |
💡 记忆口诀:
i在里面插(insert),a在后面插(append),A直接去行尾,o是open新一行。改错了一个词就用cw。
四、删除(普通模式)
| 按键 | 功能 |
|---|---|
x | 删除光标处一个字符(X 删除前一个) |
dd | 删除当前行 |
Ndd | 删除从当前行起 N 行(如 5dd) |
dw | 删除一个单词 |
d$ 或 D | 删除光标到行尾 |
d0 | 删除光标到行首 |
dG | 删除光标到文件尾 |
dgg | 删除光标到文件头 |
daw | 删除整个单词(含后面空格,光标在词中间也能删干净) |
di" | 删除引号内内容(不含引号) |
da" | 删除包括引号在内 |
di( / di) / di{ / di[ | 删除对应括号内内容 |
da{ / da} | 删除包括花括号的整个代码块 |
dit | 删除 HTML/XML 标签内内容 |
:1,10d | 删除第 1 到 10 行 |
:.,$d | 删除当前行到文件尾 |
:g/foo/d | 删除所有含 foo 的行 |
:%d | 清空整个文件(慎用!) |
💡 删除 = 剪切:vim 里删除的内容会进寄存器,用
p可以粘贴出来,所以dd既是删除也是剪切。
文本对象:di"、da{ 这类命令
文本对象(Text Objects)是 vim 里「以成对符号包围的一块文本」为单位操作,格式:操作 + i/a + 包围符。光标只要在这块文本任意位置就能操作,不用精确移动到边界:
i= inside,只处理包围符里面的内容a= around,连包围符本身一起处理
| 命令 | 作用 |
|---|---|
di" | 删除引号内内容("hello" → "") |
da" | 删除含引号("hello" → 空) |
di( / di) / di{ / di[ | 删除对应括号内内容 |
da( / da{ / da[ | 删除含括号的整个块 |
diw | 删除当前单词(光标在词中间也行) |
daw | 删除单词含后面空格 |
dit | 删除 HTML 标签内内容(如 <p>正文</p> 的「正文」) |
dat | 删除含标签(整个 <p>正文</p>) |
操作符不只有 d,换成 c、y、v 就是改、复制、选中同一块文本:
| 命令 | 作用 |
|---|---|
ci" | 修改引号内内容(改字符串神器) |
ca( | 修改含括号的整个块 |
yi" | 复制引号内内容 |
ya{ | 复制含花括号的整个块 |
vi" | 选中引号内内容(配合 "+y 复制到系统剪贴板) |
gUaw | 把当前单词转大写 |
💡 记忆:
i(inside)不带符号、a(around)带符号。编程里花括号最常用——改函数体用ci{,删整个 if 块用da{,复制 JSON 对象用ya}。写完一个{}想整体替换:光标放里面按ci{。
五、复制与粘贴
💡 命令行范围:
:命令前可带范围,%= 全文、.= 当前行、$= 文件尾、1,10= 第 1 到 10 行。下面的:%y、:.,$y就是按这个规则取范围的;同样的范围也适用于d(删)和s(替换)。
| 按键 | 功能 |
|---|---|
yy | 复制当前行(Nyy 复制 N 行,如 3yy) |
yw | 复制一个单词 |
y$ | 复制光标到行尾 |
y0 | 复制光标到行首 |
yG | 复制光标到文件尾 |
ygg | 复制光标到文件头 |
p | 粘贴到光标之后(行则粘到下一行) |
P | 粘贴到光标之前(行则粘到上一行) |
"+y | 复制到系统剪贴板(可粘贴到其他程序) |
"+p | 粘贴系统剪贴板内容(来自其他程序) |
:1,10y | 复制第 1 到 10 行 |
:%y | 复制整个文件(等价「全选复制」,最常用) |
:.y | 复制当前行(yy 的命令行写法) |
:.,$y | 复制当前行到文件尾 |
"ayy | 复制当前行到命名寄存器 a("ap 粘贴出来) |
yi" | 复制引号内内容(文本对象) |
ya{ | 复制含花括号的整个块 |
⚠️ 注意:
+剪贴板寄存器需要 vim 带+clipboard支持(vim --version里能看到)。Ubuntu 的vim自带支持;如果用vi或精简版 vim 没有,可以把选中文本用可视模式选中后"+y。p粘贴的是 vim 自己的寄存器,不经过系统剪贴板——从别处复制的内容要用"+p才能粘进来。
六、全选(重点)
vim 没有像 Ctrl+A 那样的"全选"快捷键,全选 = gg 到文件头 + 可视模式选到文件尾:
| 按键 | 功能 |
|---|---|
ggVG | 全选(gg 到第一行,V 进入行可视模式,G 选到最后一行) |
ggvG | 全选(v 字符可视模式的写法,效果相同) |
gg"+yG | 全选并复制到系统剪贴板(最常用的"全选复制") |
ggVGd | 全选并删除(清空文件) |
ggVG"+y | 全选并复制到系统剪贴板(等价写法) |
gv | 重新选中上次的选区 |
💡 全选后干什么:全选通常是为了复制走。终端里直接
gg"+yG一条龙搞定——先到文件头、进入可视模式、选到文件尾、yank 进系统剪贴板。在ssh会话里也可以用ggVG选中后再用鼠标右键 /Ctrl+Shift+C复制终端选中内容。
七、查找
| 按键 | 功能 |
|---|---|
/pattern | 向下查找 pattern(/ 后输入内容,回车执行) |
?pattern | 向上查找 pattern |
n | 跳到下一个匹配 |
N | 跳到上一个匹配 |
* | 向下查找光标所在单词 |
# | 向上查找光标所在单词 |
:set hlsearch | 高亮所有匹配(:set nohlsearch 关闭) |
:nohlsearch | 临时取消当前高亮(下次查找重新高亮) |
:set ic | 忽略大小写查找(:set noic 恢复敏感) |
💡 单词查找:光标停在一个词上按
*,vim 自动把该词作为关键字查找,改代码找引用最方便。高亮太多刺眼就:nohlsearch(可以缩写:noh)。
八、替换(重点,多种写法)
替换是 vim 最强大的功能,全部在命令行模式(先按 :)输入。基本格式:范围 + s + /旧/新/标志。
1. 按范围分
| 命令 | 作用 |
|---|---|
:s/old/new/ | 替换当前行第一个 old |
:s/old/new/g | 替换当前行全部 old(g = global,行内所有) |
:%s/old/new/g | 全文替换(% = 所有行,最常用) |
:2,10s/old/new/g | 只替换第 2 到 10 行 |
:.,$s/old/new/g | 从当前行(.)到文件尾($) |
:'<,'>s/old/new/g | 替换可视模式选中区域(选中后按 : 自动带上 '<,'>) |
2. 按标志位分
| 命令 | 作用 |
|---|---|
:%s/old/new/g | 全文替换,不确认 |
:%s/old/new/gc | 全文替换,每个匹配都确认(c = confirm,推荐!) |
:%s/old/new/gi | 忽略大小写替换(i = ignorecase) |
:%s/old/new/gn | 只统计匹配次数,不替换(n 显示 N matches on M lines) |
:s/old/new/2 | 只替换当前行第 2 个匹配 |
:%s/old/new/gI | 大小写敏感替换(I = 不忽略) |
3. 确认模式下的按键(配 c 标志)
| 按键 | 含义 |
|---|---|
y | 替换当前匹配,跳到下一个 |
n | 跳过当前匹配 |
a | 替换全部剩余匹配 |
q | 退出替换 |
l | 替换当前匹配并退出 |
4. 特殊场景
:%s#/var/www/html#/srv/web#g " 路径含 / 时用 # 当分隔符,免去转义
:%s/foo/bar/gc " 拿不准就加 c,逐个人工确认
:%s/foo//gn " 先看全文有多少个 foo
:g/foo/d " 删除所有含 foo 的行
:v/foo/d " 删除所有不含 foo 的行(v = 反向)
:%s/^// " 行首插入内容(把 new 换成要加的字)
:%s/$// " 行尾插入内容⚠️ 最常见的坑:
:%s/old/new漏了g——它只会替换每行第一个匹配,你以为全换了其实没换完。判断标准:g在末尾就是"行内全部",没有g就是"每行只换第一个"。全文替换永远用:%s/old/new/g,加c更保险。另一个坑:被替换内容含
/(比如路径、URL)时,:%s/路径/目标/g会报错E488: Trailing characters。用#当分隔符即可::%s#旧路径#新路径#g。
5. 用正则增强
替换内容支持正则,改代码非常有用:
:%s/\s\+$//g " 删除所有行尾多余空格(\s\+ 一个以上空白)
:%s/^# //g " 去掉行首的 "# "(如批量取消注释)
:%s/\<foo\>/bar/g " 只替换完整单词 foo,不碰 foobar九、撤销与重做
| 按键 | 功能 |
|---|---|
u | 撤销上一步(可连续按,多次撤销) |
Ctrl+R | 重做(恢复被撤销的操作) |
U | 撤销当前行的所有修改(回到刚到这行时的状态) |
:undo N | 回退到第 N 步之前 |
💡 vim 的撤销是树状的:撤销后再做别的操作,之前的"未来"分支不会丢。改坏了大段内容,最快是
:q!不保存重开,或者狂按u。
十、多文件与窗口
| 命令 | 功能 |
|---|---|
:e 文件 | 打开新文件(替换当前缓冲区) |
:bn :bp | 切换到下一个 / 上一个文件 |
:ls | 列出所有打开的缓冲区 |
:sp :vsp | 水平 / 垂直分屏 |
Ctrl+W 然后 h/j/k/l | 在分屏窗口间移动光标 |
:tabnew 文件 | 新标签页打开 |
十一、小技巧
- 临时改系统文件:改
/etc/xxx只读文件时:w !sudo tee %可以绕过权限保存。 - 行号:
:set number显示行号,:set nu是缩写;想永久生效写入~/.vimrc。 - 帮助:
:help打开完整文档,:help :s查看替换命令帮助,:help registers看寄存器。按q关闭帮助窗口。 - 看当前状态:普通模式按
Ctrl+G显示文件路径、行数、光标位置。 - 新学 vim:终端里跑
vimtutor,官方 30 分钟交互教程,学完基础命令就全了。 - 常用缩写:
:wq与:x等价;:q!与ZQ等价;:set nu是:set number缩写。
十二、速查表总览(一页版)
| 想做什么 | 按键 |
|---|---|
| 全选 | ggVG |
| 全选并复制到系统剪贴板 | gg"+yG |
| 复制当前行 | yy |
| 复制整个文件 | :%y |
| 粘贴 | p / P |
| 删除当前行(剪切) | dd |
| 删除引号内内容 | di" |
| 修改引号内内容 | ci" |
| 全文替换 | :%s/old/new/g |
| 全文替换(逐个确认) | :%s/old/new/gc |
| 查找 | /内容 回车,n 下一个 |
| 撤销 / 重做 | u / Ctrl+R |
| 保存退出 | :wq(或 ZZ) |
| 不保存退出 | :q!(或 ZQ) |
✅ 实战验证:本文所有命令在 Ubuntu 24.04、VIM 9.1(Debian 版)实测通过。替换部分逐条验证了
:%s/foo/FOO/g全文替换、:1s/foo/FOO/单行首个替换、:2,3s/foo/FOO/g范围替换、:s/foo/FOO/2只换第 2 个匹配、set ic忽略大小写、#分隔符处理路径、:g/foo/d与:v/foo/d按条件删行;计数模式输出3 matches on 2 lines(中文环境显示"2 行 3 个匹配")。文本对象验证了di"删除引号内(foo("hello world")→foo(""))、da"删除含引号(→foo())、da{删除含花括号块(→if (x))、di(删除括号内(→call(););范围复制删除验证了:%y复制全文后粘贴得到完整 6 行、:1,2d删除第 1-2 行只剩第 3 行、:.,$d从当前行删到文件尾只剩首行;复制粘贴验证了ggVG全选后 yank 粘贴得到完整重复内容、:1,3y批量复制;+clipboard剪贴板支持在vim --version中确认开启。若你的 vim 报E492: Not an editor command,通常是精简版 vim(如vi)缺功能,安装完整版即可:sudo apt install vim。
