1. 先把这个老古董的底层逻辑讲透
如果你问一个老运维或者后端开发,工作中最离不开的编辑器是什么,十有八九会得到一个答案:VI(或者它的增强版VIM)。这玩意儿从1976年诞生到现在,外观几乎没怎么变过,黑底白字,没有菜单,没有按钮,第一次打开甚至不知道怎么退出。但就是这样一个“老古董”,在服务器上、在Docker容器里、在远程开发环境中,依然是无可替代的存在。
很多新手第一次进VI会觉得莫名其妙——为什么打开文件后敲的字不显示?为什么光标动得那么别扭?为什么按个方向键都会跳出ABCD?这些困惑的根源在于,VI和你平时用的记事本、Word、VS Code完全是两种物种。记事本是“输入型编辑器”,你敲什么就显示什么;VI是“命令型编辑器”,它有自己独立的一套模式体系。
VI的核心设计理念是:让手不离开键盘主区域就能完成所有操作。在图形界面时代听上去很落后,但当你在没有鼠标、没有图形界面的Linux服务器终端里修改配置时,这套设计就成了效率神器。VI的创造者Bill Joy当年是为了在带宽极低的慢速终端上编辑文件,每传一个字符都要钱,于是他把光标移动、删除、翻页这些高频操作浓缩成单个按键,形成了一套独立的“编辑语言”。
所以在VI上,第一个要破除的思维定式是:VI不是用来“打字”的,而是用来“操作文本”的。它的常态模式叫Normal模式(普通模式),在这个模式里,你的每个按键都是一个命令,比如j代表向下移动一行,w代表跳到下一个词,dd代表删除整行。只有当你明确进入Insert模式(插入模式)后,键盘才回归打字功能。
把这一点想通了,VI的学习路径就清晰了:先用命令控制光标和文本,把它想象成你在“驾驶”编辑器,而不是在“与之对话”。我见过很多人学了两三年还是只会用i进入插入然后方向键移动,到最后按ESC退出来都不知道怎么保存退出,这就是没有在意识层面完成转换。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 文件操作与光标移动:先打通最常用的肌肉记忆
2.1 打开、保存与退出:四个命令必须背下来
VI的打开命令很简单,在终端里输入:
bash复制vi 文件名
如果文件存在就打开,不存在就新建。但打开之后才是重头戏。很多人的第一个坎就是:怎么保存、怎么退出。我总结了一个四命令对照表,初学者建议贴在显示器边上看两天:
| 场景 | 命令 | 说明 |
|---|---|---|
| 保存但不退出 | :w |
写入磁盘 |
| 退出不保存 | :q! |
强制退出,放弃所有修改 |
| 保存并退出 | :wq |
等价于 ZZ(大写) |
| 强制保存退出 | :wq! |
只读文件需要加感叹号 |
注意,这四个命令是在Normal模式下按 : 进入命令行模式来执行的,按下冒号后输入内容不会出现在文件里,而是出现在屏幕最底部。
我在现实里遇到最多的问题是:用户进了VI后想退出,按了ESC但系统发出“嘀”的一声,然后一脸懵。这里有个技巧——如果你不确定目前处于什么模式,连按两次ESC一定能回到Normal模式。再小一点说,VI的退出命令设计成 q 是有讲究的,它是Quit的首字母,逻辑清晰。之所以还要区分 :q 和 :q!,是因为VI默认保护未保存的修改,没有 ! 是不让你放弃退出,这其实是个防呆设计,避免你辛辛苦苦打了半天不小心全丢了。
2.2 光标移动:从逐字到逐屏的完整阶梯
光标移动是VI操作频率最高的动作,也是最需要形成肌肉记忆的部分。新手最大的误区是进入VI后先用方向键移动,然后再看屏幕。方向键在VI里也能用(取决于终端支持情况),但效率低,而且换到某些环境或精简版VI下就会失灵。真正好用的方式是用 hjkl 四个字母:
h:左移一个字符j:下移一行k:上移一行l:右移一个字符
为什么偏偏选这四个键?答案很简单:在标准键盘上,h 在最左边,l 在最右边,j 下方有个小凸起帮助盲定位,它们占据了右手食指和中指的天然位置,几乎不用移动手腕就能触达。
字符级移动显然是慢的,因此Vi提供了大量“跳级”命令,效率和移动尺度直接挂钩:
| 按键 | 移动尺度 | 实际效果 |
|---|---|---|
w |
到下一个单词开头 | 按词跳,快很多 |
b |
回到上一个单词开头 | 配合w前进/后退 |
e |
跳到当前词尾 | 适合快速定位到行的末尾部分 |
0 |
到行首 | 不带前导空格 |
^ |
到行首 | 跳过一个或多个空格/制表符,到当前行第一个内容字符 |
$ |
到行尾 | shift+4 |
gg |
到文件第一行 | 连按两次g |
G |
到文件最后一行 | shift+g |
H |
屏幕顶部 | 记忆点是Home的缩写 |
M |
屏幕中部 | Middle |
L |
屏幕底部 | Last |
Ctrl+d |
下滚半屏 | 记忆是Down |
Ctrl+u |
上滚半屏 | Up |
Ctrl+f |
下滚整屏 | Forward |
Ctrl+b |
上滚整屏 | Backward |
我个人最常用的移动组合是:gg 跳文件头,G 跳文件尾,Ctrl+d 半页半页地往下扫,到目标区域后用 w 和 b 按词定位。这套习惯在我改几万行的配置文件时非常受用。还可以在任何移动命令前加数字表示重复次数,比如 5j 表示向下跳5行,3w 表示向前跳3个词,12G 表示跳到第12行。这种“数字+命令”的语法贯穿整个VI的编辑体系,是进阶的关键。
2.3 补个可视化位置提示:底行状态栏
很多新手问“我现在在第几行”“文件总共多少行”,这个在正常编辑时不确定,有几个办法:
Ctrl+g:在屏幕底部显示当前文件名、总行数、当前行位置百分比:set nu:打出行的行号,注意不是插入到文件,是界面显示:set nonu:取消行号- 输入行号后按
G:直接跳到指定行,比如输入87再按G,光标到第87行
这个在排查日志文件时特别好用。你拿到一个报错提示“第123行有空指针”,就能用 123G 一键到达。
有一个小技巧我一直推荐:在处理大型日志或配置文件时,用
Ctrl+g看一眼百分比进度,再配合搜索定位,比一屏一屏翻高效得多。
3. 编辑操作的精髓:动词加名词的命令语言
3.1 进入插入模式:不只是 i 一个按键
VI的编辑操作入门容易,精深很难。先说要进入插入模式,其实有好几种,每种对应不同落点:
i:光标当前字符前插入I:跳到当前行行首插入a:光标当前字符后插入A:跳到当前行行尾插入o:在当前行下方新开一行进入插入O:在当前行上方新开一行进入插入s:删除当前字符并进入插入S:清空当前行所有内容并进入插入cw:删除当前词并进入插入cc:清空整行并进入插入
这些命令看似多,实际上都是“意图表达”:你是想在词后追加、还是想在行尾追加、还是想重写一个词,每种动作在文本编辑里出现的频率完全不同。我举例一个实际场景:你看到一个配置文件,发现少了一个分号,光标动到这个行尾去修改的期望动作是 A;(大写的A等价于行尾插入,然后直接补分号)再加ESC,全程3个按键就搞定。而如果不动脑,有人会先移动到最后、再i、再打上分号、再ESC,绕了一圈。
在这里我特别想提醒一件事:修改代码时,尽量用 cw、cc 这种“删除并进入插入”的组合,而不是先 x 删掉再 i 进去补。为什么?因为 cw 是“替换词”的思维,几乎不需要关心删除范围,也不用在中途切换模式——你把一个错误变量名改掉的步骤从多次缩减到一次,这种细微的变化在日复一日的编辑中积累出的时间差非常可观。
3.2 删除、复制、粘贴:学会组合命令后你就不想再用鼠标了
先列最常用的删除命令:
x:删除当前字符(可以理解为大号退格键)X:删除光标前的一个字符dd:删除当前整行D:从光标位置删到行尾dw:删除到下一个词的开头d0:从光标位置删到行首d$:从光标位置删到行尾dG:从当前行删到文件末尾
再列复制粘贴:
yy:复制当前整行yw:复制一个词y$:复制光标到行尾的内容p:粘贴到光标之后P:粘贴到光标之前
这里最值得讲的是 d(delete)、y(yank)这两个命令的本质——它们都是“动词”,后面可以接“名词”来定义作用范围。w 是一个词,$ 是行尾,0 是行首,G 是文件全局。一旦你接受了这个设定,你可以随意造句:
d3w:删除三个词y2j:复制当前行往下两行(共三行)dH:删除当前屏幕顶部到光标的内容?(H表示屏幕顶,所以是删到顶)
这就是VI特有的“组合式编辑语言”。用久了之后,你连光标都不用移来移去,只要明确地告诉编辑器“从当前位置到某处做某操作”,这就是很多人说的“手不离键盘,思路不打断”。
粘贴在删除之后有个小坑:如果我只想删除一个字符 x,那么下一次粘贴 p 会把那个字符粘回来。其实 p 粘贴的是最近一次删除或复制的内容,所以删除完如果马上粘贴,往往会“起死回生”。防止误操作的小技巧是,在你需要大量粘贴前,先复制一个完整的内容占住剪贴板,比如 yy 一次,再粘贴就会把落行粘出来而不是上次的零散字符。
3.3 撤销与重做:打破“后悔药”限制
u:撤销上一步操作Ctrl+r:重做(撤销撤多了就按这个)U:撤销对当前行的所有修改
这几个命令看似平平无奇,实则是编辑器的底线保障。VI的撤销机制是“按操作单元”的,而不是按次数的。你输入连续插入的一串文字,退出插入模式的那一刻算一次操作,按一次 u 全部撤回。如果你的插入把一个词改了又改了回来,退出后按一次 u,整段插入都会被清除。
这就意味着:为了可撤销性,每次在插入模式里改一小段就ESC退出一次,能有效提升你可控回退的粒度。我在写代码配置文件时有个习惯,每次修改完一两个逻辑块就退出插入模式一次,因为多次小范围修改对应多次独立撤销的次数,万一改错了能精确回退到特定状态而不是一口气回退一大段。
提示:
U这个命令对整行生效,如果你在一行里做了七八个修改后又后悔,按U可以直接回到最初状态,比连按u次很多次更直接。
4. 快速定位利器:搜索替换与多种高级跳转
4.1 行内定位:f 系列快速移动
VI里很常见的一个场景是,光标已经在这行,但想要定位到行内的某个字符进行修改。你当然可以反复按 l 一步步挪,但更快的做法是用 f + 字符来“查找并跳到对应位置”:
fx:跳到本行下一个字符x所在位置Fx:跳到本行上一个字符x;:重复上一次的f查找,继续向后找,:反向重复
举个例子,某行是 proxy_pass http://backend_server:8080;,我想把8080改成8090,光标在行首的话,不用走过去,直接 f8 就跳到本行第一个 8 的位置,然后 r9(替换成9)一下搞定。这是不是比挪挪挪快多了?
f + t 还有个近亲 t,它跳到目标字符的前一个字符,常用于想改动到某字符之间的内容时。比如 dtt 就是删除到下一个t字符前的所有内容,很多精致的文本操作靠这个一记完成。
4.2 全文件搜索:让/的用法深入骨髓
/ 加上关键词然后回车,是全文向下搜索;? 加关键词则是向上搜索。搜索结果中:
n:跳向下一个匹配N:跳向上一个匹配
搜索时忽略大小写可以先用 :set ic,取消忽略则 :set noic,也可以直接在搜索词后面加 \c 表示该次搜索忽略大小写。
这里的搜索用的是正则匹配。初学者可能只会搜单词,但老手会用 /^foo 来搜行首是foo的行,用 /bar$ 来搜行尾是bar的行。最有用的一个玩法:把光标放在一个词上按 * 键,VI会立刻向下搜索并跳到下一个相同词的位置;按 # 向上搜索。这个命令在你浏览代码时太常用了,都不用先打斜杠再输入单词,直接 * 完再按 n 一路扫下去,看代码里每个变量出现的位置极其高效。
4.3 替换操作:从单次到全文件
VI的替换操作在命令行模式执行,基础语法是:
vim复制:s/旧内容/新内容/
默认只替换当前行第一个匹配。要替换全行所有匹配就加 g:
vim复制:s/旧内容/新内容/g
要替换全文件则要加上范围前缀 %:
vim复制:%s/旧内容/新内容/g
这个 % 代表所有行。如果是针对某几行区间,比如10到20行:
vim复制:10,20s/旧内容/新内容/g
在真实操作中,最稳妥的替换流程是:先用 :%s/旧内容/新内容/gc 加一个 c 表示每次替换前需要用户确认,按 y 替换,按 n 跳过。文件里有些不确定不能改的地方这样处理就很稳。很多人担心替换把不想改的地方一起改了,加个 c 确认参数是经验之谈,强烈建议养成习惯。
替换操作中还有个逃逸陷阱:如果旧内容里包含 / 字符,比如要替换文件路径 /home/user/xxx 为 /data/xxx,由于 / 是替换命令的分隔符,你需要用反斜杠转义,样式很丑,像这样:
vim复制:%s/\/home\/user\/xxx/\/data\/xxx/g
为了避免这种乌压压的转义,可以把分隔符替换成别的符号,比如 # 或 @:
vim复制:%s#/home/user/xxx#/data/xxx#g
这样路径就照抄不用转义了,阅读性瞬间高一个档次。多数字符串替换的场景(比如URL、路径)都适合改用其他分隔符。
4.4 可视选择与批量操作
说完了常规模式,再补一个可视化模式。按下 v(字符可视化)进入,然后通过移动扩展选择区,选好后按 d 删除、按 y 复制、按 c 修改。按 V(大写)是行可视化,一次选中一条或多条完整行;Ctrl+v 进入块可视化,可以选择矩形区域,这就进入真正的高阶玩法:
以多行行首加注释为例:先用 Ctrl+v 进入块模式,将光标移行首并按 j(或更多字母键)拉到多行行首,按 I,输入 // 或 #,再ESC,所有被选行的行首会同时出现注释符号——这个在改代码时批量注释或取消注释非常方便。若想去掉每行行首的注释符号,就在块模式下选中那些符号,直接 x 删除,也能一并清掉。
可视化模式的存在能让不太熟悉命令的人先通过“肉眼选中”,再施加操作,是从文字模式转换到直觉操作的重要桥梁。如果你是新手,在弄不清怎么组合命令之前,大可用 v 选好后按 d 删除,照样是有效的。
5. 多文件编辑、宏录制与分屏操作:升阶之路
5.1 多文件和分屏:同时审阅多个文件
实际项目不太可能是单文件作业,VI提供了多种多文件方案。最基础的是打开多个文件:
bash复制vi file1.txt file2.txt
在VI内部一次只能看见一个文件,切换用:
:n:跳到下一个文件:prev:回到上一个文件:files:列出所有打开的文件,带%的是当前文件
另一种特别流行的是分屏模式,在打开的VI里直接拆分窗口:
:sp filename:横向切分并打开新文件:vsp filename:纵向切分并打开新文件Ctrl+w w:在窗口间跳转Ctrl+w q:关闭当前窗口Ctrl+w =:让所有窗口等宽等高
在查看代码时,我习惯同时打开源文件和对应的日志或配置文件,用纵向分屏 :vsp 就能左右对照。比来回切换文件要省太多时间。
要是只想着急看一眼另一个文件再回到原来的,还有一条超实用命令::e 文件名 重新加载文件到当前缓冲区(等于换一个文件看);如果当前文件有修改又没有保存,VI会拒绝切换,此时可以 :e! 文件名 放弃当前修改强制切换。
5.2 宏录制:重复操作自动化
如果有一串重复的编辑命令,比如要把日志里每一行的第二列和第三列交换位置,纯手工做几十次会让人崩溃,用VI的宏命令可以轻松办到。
宏的含义是把一系列键盘操作录下来,然后反复回放。录制的语法是:
- Normal模式下按
q加一个字母寄存器名字(比如a),开始录制,左下角显示“recording” - 执行你要重复的一组操作
- 按
q结束录制 - 用
@a回放一次,用@@回放上一次的宏
举个例子:假设有一份姓名和电话号码的列表,格式为 张三 138xxxx 北京,需要删除每行中间的“138xxxx”。可以先在第一行录制宏:
q a(开始录制)ww跳到第二列开头,dW删除该列及空格j跳到下一行行首q结束录制- 然后
100@a回放100次,完成批量删除
宏录制适合那些算法思维清晰、步骤机械的操作。尽管现在很多人推荐用sed、awk处理列数据,但如果只是交互式地看一眼并修改,宏反而是最快路径。尤其是处理配置文件里重复替换一长串重复块时,把操作录下来往后刷,省下的可远不止几分钟。
5.3 缩写、补全与寄存器:日常高频编辑提效
再讲几个VI里容易被人忽略却不经意间能提效的“甜点”级别功能:
:abbr imo 我理解错了,输入imo按空格自动扩展为“我理解错了”(这种常用于写邮件、补注释时固定模板)Ctrl+n或Ctrl+p:在插入模式下自动补齐文件里已有的词,类似IDE的代码补全"+y与"+p:与系统剪贴板交互。尤其在使用 VIM for Windows 或一些包含图形支持的终端时非常有用
系统剪切板和VI内部的剪贴板默认是隔离的,你按 yy 复制的内容用 Ctrl+v 不一定能粘到别的程序里去。要解决这个问题,在VIM里用 "+yy 把内容复制到“+”寄存器,在外部用 Ctrl+v 能粘贴出来;反过来同理。需要提醒的是,你系统剪贴板是否正常工作还与终端版本有关,只要版本相对较新,这组命令都是好用的。
5.4 VI配置文件与个性化
VI还有个用户级配置文件 .vimrc,可以自定义按键映射和默认设置,推荐几个我常在配置文件里启用的选项:
vim复制set nu " 显示行号
set expandtab " tab转换成空格
set shiftwidth=4 " 自动缩进为4空格
set tabstop=4 " tab宽度4
set hlsearch " 搜索高亮
set incsearch " 随输入实时搜索
syntax on " 开启语法高亮
set mouse=a " 支持鼠标操作
等等。有些新用户刚打开VIM不喜欢高亮或者不喜欢行号,就把这些配置写进 ~/.vimrc。这里要注意,不同系统对配置文件的命名可能略有差异,VIM读的是 ~/.vimrc,传统VI可能不读,但现代Linux发行版中将VI映射成VIM的版本几乎是铁板一块,配置文件通常有效。
我诚实的建议是:配置文件不用搞得很花哨,先把 set nu、syntax on 这种基础项开开,后续根据自己的需求把常用映射加进去。我在自己的配置里把 ; 映射为 :,这样就不用按Shift了,习惯之后省力不少;再用Leader键简化了一些高频操作。但这些都属于锦上添花,真正的基础还是在命令语言的掌握。
6. 新手进阶必经的6个常见问题与急救指南
6.1 保存不了?退出又退不了?先分清这几个原因
最典型的场景:修改了系统的配置文件后输入 :wq,报错说“E45: 'readonly' option is set (add ! to override)”。意思是文件是只读的,你没有写权限,但自己又是root很迷惑。这时候先确认你是不是真的在当前用户下拥有该文件的写权限:
bash复制ls -l 文件名
如果文件所有者不是当前用户且没有写权限,再用 sudo vi 文件名 重来(不要直接在普通用户跑 :wq! 想强制,没有权限还是要没权限的)。注意一些极端情况下,VI的 :wq! 对只读文件不一定成功,那说明你的用户对磁盘也没有写权限。
如果遇到磁盘满了,你辛辛苦苦改完却保存不上,报错提示没有空间。这时候不要退出VI,内部输入 :!df -h 可以在不退出的情况下查看磁盘是否满了,如果确认满了,就清理点空间再保存,或者用 :w /tmp/找到的文件名 先保存到其他分区再想办法。
6.2 方向键失灵或输字符变成ABCD?
这可以说是十几年前新手最崩溃的问题。原因是VI的模式体系而终端处于完全不支持某组按键序列的现象。尤其是一些精简安装的系统上,Insert模式下按方向键不会移动光标,而会出现:
text复制^[[A
^[[B
或者更糟的情况是直接输入了ABCD字母。为了规避这类问题,最好就是忘掉方向键,用 hjkl 替代(这本来也是VI的设计初衷)。真正老练的人根本不会在插入模式里大范围移动光标——要改哪里先ESC,用Normal模式的移动定位更精准,再进去改。这种习惯本身也是在终端环境崩溃状态下保持操作自如的保险。
6.3 搜索时文件乱跳,高亮一直不消怎么办?
当你执行了 / 搜索后,退出编辑模式依然能看到匹配的地方高亮着一片,看起来碍眼。想关掉就用:
vim复制:nohlsearch
或者缩写为 :noh。如果不想让搜索有高亮,也可以在配置文件里写明 set nohlsearch。另外,当搜索词在文件中出现很多次,想回到原来的行,按 Ctrl+o 可以回跳上一次变更位置,再按 Ctrl+i 前进,这个逻辑与浏览器历史记录是一样的。
6.4 改错了想回退却发现回不去了?
在VI中撤消不只是 u。如果你的终端没有 Ctrl+r 重做,可以试试在Normal模式下按 :redo。但是如果你不小心退出了VI再重新打开发现所有修改都白改了,那就无能为力了——除非你之前开了swap文件(~ 或 .文件名.swp)。VI会为正在编辑的文件建一个隐藏的交换文件,当你处理得非常糟糕时可以用 :recover 找回上次的内容。这在终端突然断电的情况下作用显著。
提醒:交换文件本身就是双刃剑。如果你编辑时没有正常退出,下次打开会提示检测到一个.swp文件,可选择“恢复(Recovery)”或者“删除(Delete)”它。如果其实是另一个进程还在编辑同一文件,千万不要贸然删.swp,否则可能破坏另一个程序的编辑操作。
6.5 二进制文件打开乱码如何规避?
打开二进制或非纯文本文件时,VI会用一堆乱码展示内容,有时还会往文件里加内容。现代VIM能识别“二进制”模式,但普通VI版本很容易把原本好好的文件搞坏。我的建议是:对于二进制文件,先备份再用其他工具处理,比如 hexdump -C 查看十六进制内容。如果确实需要编辑,启动时可以:vim -b 文件,进入后再用 :%!xxd 转成十六进制编辑,编辑完 :%!xxd -r 转回二进制再保存。这个操作适合专业开发人员。
6.6 搜索替换中特殊字符与大小写的高频踩坑
在使用正则替换时有个小坑:比如回替换“foo”但不想误伤“food”“foolish”,光标移到目标词后备注要用 \< \> 来标记边界:
vim复制:%s/\<foo\>/bar/g
同理,搜索时也能配合边界:/\<cat\> 只匹配独立的cat不匹配catch。另外如果用 / 搜索 * 符号时,由于 * 在正则里代表“任意多前驱字符”,所以要用转义 /\*。这也是为什么刚开始接触搜索大家比较烦。不过整体而言,正则处理文本在编辑器中真的强,建议系统过一遍常见元字符的用法。
7. 从一个命令入门到形成习惯,我的亲身体会
所有离开应用的词汇学习都是无效的。VI也是一样,如果你只是把这些命令抄进备忘,从来不去敲,永远记不住。我早年学VI时用过最笨也最有效的方法:把所有日常工作从图形IDE挪到VI里做,一开始效率断崖下降,一天只能写之前一半的内容,但坚持两周后,适应了这个模式,效率反超了。再往后,看到命令行里的文件第一反应不是 cat,而是直接 vi 进去扫一眼再改改,思考的流畅性是非常高的。
关于跨工具的迁移我还想说一句:现在VS Code、JetBrains系列都有VI模拟插件,原因是这套编辑逻辑的效率得到公认。即使在图形界面环境下,只要你在编辑器里装上VI插件,同样的肌肉记忆依然能复用。这意味着学VI不是学一个“老古董”技能,而是获得一套跨工具的输入范式。如果你现在还没上手,从今天开始每天所有文本修改都用 vi 完成,不出一个月,你就知道为什么运维同事能在不看键盘的情况下日改三百行配置了。
最后分享个小技巧:VI自带教程,在shell里输入 vimtutor 就能打开一个互动教程,跟着走一遍约30分钟,就把最基础的操作覆盖全了。如果想系统深入,随时在VI里按下 :help 翻用户手册——这本手册的内容之多、组织之好,比网上绝大多数博客教程都扎实。用VI最好的学习方法很简单:有一天你和它之间的交互不再经过思考,那你就真的入门了。
