第一次听到还有人专门写 vi 教程的时候,我其实是有点抗拒的。周围同事用 VS Code 用惯了,连鼠标都不想碰,看到我在终端里按 : 键想保存文件,第一反应是:“这玩意还能活到今天?” 但真到了服务器上排查问题、改配置文件、在没有图形界面的环境里应急,vi 依然是唯一靠得住的东西。这篇内容不讲花哨的插件体系,只讲我这些年用 vi 的真实习惯、踩过的坑,以及一套新手也能直接照着用的操作流程。
vi 是什么,能做什么,适合谁来学?一句话:vi 是 Unix/Linux 系统自带的标准文本编辑器,几乎所有发行版都会内置,程序员要改配置、看代码、写脚本,都会碰到它。适合所有需要在命令行环境工作的人,尤其是运维、后端开发和刚接触 Linux 的学生。不用怕它门槛高,真正用顺之后,效率提升非常明显。
1. 为什么现在还要学 vi
1.1 vi、vim 和 nvi 的区别
在终端里输入 vi,你打开的可能是 vim,也可能是传统的 vi,这取决于系统装了什么。vim 全称是 Vi IMproved,是在原版 vi 基础上增加了语法高亮、多级撤销、可视模式等功能的增强版,但它的核心操作理念和 vi 完全一致。有些精简系统里只有 nvi,这是 BSD 系统上的 vi 克隆版,功能略有区别,按键习惯基本相通。
我平时在 Ubuntu 和 CentOS 上工作,默认的 vi 通常就是 vim.tiny 或完整 vim。建议你敲 vi --version 看一下版本,如果输出显示 VIM - Vi IMproved,那用的就是 vim。如果是完整的 vim,后面很多高级功能都能用,比如语法高亮、多窗口;如果只有 tiny 版本,很多扩展插件就装不了。学校里老教材讲的纯 vi 操作,在这里依然适用,因为 vim 刻意保持了兼容性。所以不用纠结名字,把 vi 当作一个动词、一个命令来学,性质是一样的。
bash复制# 查看当前打开的编辑器和版本
vi --version
# 如果只想用纯 vi 模式启动 vim
vi -N
1.2 什么场景适合用 vi
我总结下来,vi 最适合三类场景。第一,远程登录服务器:通过 SSH 连到没有图形界面的机器上,改 Nginx 配置、看系统日志、写启动脚本,vi 是系统自带、几乎不可能不存在的编辑器,你不用费劲装任何东西。第二,紧急修改文件:比如写 crontab 定时任务,命令本身会直接调用 vi 作为编辑器;再比如用 sudo vi /etc/hosts 临时改个域名映射,鼠标操作反而会拖慢速度。第三,纯键盘操作需求:写代码时手不离开键盘,用 vi 的快捷键完成移动、删除、替换,比在代码编辑器里用鼠标选文本再按删除键快得多。
很多朋友问我,是不是必须先把 vi 背得滚瓜烂熟才能上服务器?完全不需要。你只需要掌握打开文件、移动光标、插入文本、保存退出这四件事,就能应付日常操作,剩下的边用边查。真正的准则是:vi 不要求你全记住,但要求你知道自己现在处于什么模式。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 理解 vi 的模式,比背快捷键更重要
2.1 三种基本模式和切换方法
vi 和 Windows 记事本最大的区别就是模式。notepad 只有一种状态,键盘输什么就是什么;vi 默认处于“正常模式”,在这个模式下,键盘上的字母不是用来输入的,而是用来执行操作的,比如 j 是向下移动,x 是删除光标所在字符,dd 是删除整行。如果你在正常模式下按了一堆字母,发现文件里没有出现文字,不要慌,那不是坏了,而是你正在操作模式里。
要真正往文件里写内容,需要按 i 进入“插入模式”,这时候键盘才变成正常的输入状态。插入模式下,屏幕左下角会出现 -- INSERT -- 字样(vim 会显示,纯 vi 不一定显示)。要退出插入模式回到正常模式,按 Esc 键,或者按 Ctrl + [,后者在键盘上更顺手,不容易误触。
除了正常模式和插入模式,还有一个“命令行模式”。按 : 就会进入这个模式,屏幕最底部出现一条命令输入区,可以执行 w 保存、q 退出、s/old/new/g 替换文本等命令。这三个模式的切换关系,是初学 vi 最容易乱的地方。我建议每次做完操作都习惯性按一次 Esc,确认自己已经回到正常模式,再按下一组命令,避免命令串在一起被误解。
2.2 必须先记住的 20 个按键
这里我按“立即要用的优先级”整理一份基础键位,你不需要一次背完,先从第一组开始练。
| 操作类型 | 按键 | 作用说明 |
|---|---|---|
| 光标移动 | h / j / k / l |
左 / 下 / 上 / 右移动一个字符 |
| 光标移动 | w / b |
跳到下一个词开头 / 回到上一个词开头 |
| 行内跳转 | 0 / $ |
跳到行首(第 0 列)/ 跳到行尾 |
| 进入插入 | i / a / o |
在光标前插入 / 在光标后追加 / 在当前行下方新建一行并插入 |
| 删除 | x / dd |
删除光标当前字符 / 删除整行 |
| 复制粘贴 | yy / p |
复制当前行 / 粘贴到光标下方 |
| 撤销重做 | u / Ctrl + r |
撤销一步 / 重做一步 |
| 保存退出 | :w / :q / :wq / :q! |
保存 / 退出 / 保存并退出 / 强制退出不保存 |
不要试图同时记住全部,我建议新手第一天只记 h j k l、i、dd、u、:wq,练熟了再逐步扩展。这些键位奇怪的地方在于方向键,h 在左、l 在右,其实这是有历史原因的,早期键盘没有独立方向键,vim 的设计者为了不让手离开字母区,故意选用了这四个键。所以你按方向键也能动,但手要移来移去,效率就下来了。想要进阶,用 hjkl 是必经之路。
2.3 模式混乱时的自救
刚接触 vi 时最常见的状况是:插入模式下打了一堆字,想保存却忘了按 Esc,结果把 :wq 几个字符直接输进了文档里。或者正常模式下误按了 r 键,以为还能输入,结果每次按一个字母就把当前字符替换掉一个。这都是模式理解不到位导致的。
遇到模式混乱,先停下来,连续按两次 Esc,回到正常模式,再看屏幕底部有没有冒号提示。如果误输入了内容,在正常模式下按 u 撤销,按一次撤销一步,多按几次就能把误输入的文字全部撤销掉。如果你已经按了 :wq 但文本里出现了 :wq 这样的字符串,用撤销把这几步退回去就行。别在有 -- INSERT -- 提示的状态下输入命令,那是最基本的一条纪律。
3. 一套能直接上手的工作流程
3.1 打开文件、写入和保存
先说最简单的完整工作流:打开文件、修改、保存退出。在终端里执行:
bash复制vi /home/user/test.sh
如果文件不存在,vi 会打开一个空缓冲区,左下角显示类似 "test.sh" [新文件] 的提示。此时按 i 进入插入模式,输入内容。输入完成后按 Esc 回到正常模式,再输入 :wq 并回车。w 是 write,写盘保存;q 是 quit,退出。合起来就是保存并退出。如果你想临时不保存退出,执行 :q!,感叹号表示强制,放弃所有未保存的修改。这个组合是服务器上用得最多的两个命令,没有之一。
这里有个细节很多人没注意:vi 在纯命令行模式下是看不到编辑文件名的,文件名只在打开和保存时显示。所以我自己习惯在正常模式下按 Ctrl + G 查看当前文件的完整路径、总行数和光标位置百分比。在 vim 里也可以输入 :f 查看当前文件信息。改到一半忘记文件在哪,这个命令比切到终端再用 pwd 快。
3.2 删除、替换、复制与粘贴
删除操作在 vi 里不是按退格键,而是用一组基于“对象”的组合键。你可能听过一个说法:vi 的命令是由“操作 + 范围 + 对象”组成的,理解了这套组合逻辑,几乎所有复杂操作都能推出来。举个例子,d 是删除命令,w 是单词对象,那么 dw 的意思是删除光标到单词末尾的内容;dd 是删除整行,因为第二个 d 表示对整行操作;d$ 是删除从光标位置到行尾的内容,d0 是删除从光标位置到行首的内容。
复制粘贴也遵循同样的逻辑。y 是复制(yank),yy 复制当前整行,yw 复制一个单词,p 在光标下方粘贴,P(大写)在光标上方粘贴。这里有个被新手忽略的坑:vi 的剪贴板和系统剪贴板不是同一个概念,你在系统其他程序里复制的文本,不能在 vi 里直接用 p 粘贴,vi 有自己的寄存器。如果你确实需要和系统剪贴板互通,得在 vim 里确认当前版本支持 clipboard 特性:
bash复制vi --version | grep clipboard
如果输出带有 +clipboard,说明支持,可以用 "+p 粘贴系统剪贴板的内容,用 "+y 把 vi 里选中的内容复制到系统剪贴板。如果不支持,换个支持 clipboard 的 vim 版本,或者直接在终端命令行层面处理。这是很多人进了 vi 发现粘贴不了外部文本时的第一反应:“这破编辑器真难用”,其实只是寄存器机制没搞清楚。
3.3 可视模式与区块操作
vim 比传统 vi 多了一个“可视模式”,能像普通编辑器那样选中一段文字,然后统一操作。在正常模式下按 v 进入可视模式,移动光标选中范围,选好后按 y 复制、d 删除、x 剪切,或者直接按 :s 对选中区域做替换。这个模式对新手特别友好,因为你有视觉反馈,知道自己选中了什么。
还有一个更厉害的是 Ctrl + v 进入的“块可视模式”,它能选中一个矩形区域。比如多行配置文件里,每一行开头都有一个 # 注释符,你想一次性删除这些井号,就可以把光标移到第一行注释符上,按 Ctrl + v,移动光标列选到每一行的同行字符,选中多行后按 x,这些字符就被整齐地删掉了。这个操作对批量写配置非常有用。
3.4 撤销与恢复
vi 的撤销是分级的,按 u 撤销一步,再按 u 再撤销一步。如果你撤销错了,按 Ctrl + r 重做。在 vim 里,撤销不只是简单记步,它会记录你每次进入插入模式到退出插入模式之间的所有输入,算作一个“修改单位”。比如你进入插入模式后一口气敲了 20 个字符,按 Esc 退出来,这时候按一次 u,这 20 个字符会作为一个整体消失。这个设计很合理,避免了一次按一个字符撤销半天。
还有个小技巧:如果对文件的改动很大,想回到最近一次保存的状态,用正常模式下的 :e!。这个命令的意思是“重新加载当前文件,并放弃所有未保存的修改”,相当于把时间倒退回你上一次 :w 的时候。我经常在试验性修改配置时用这一招,改乱了直接回到上次保存点,比一遍遍撤销快多了。
4. 定位、搜索与替换的实用技巧
4.1 光标的快速移动
文件长了以后,用 j、k 一行行移动就有点慢了。vi 提供了几个层级移动方式,你可以按“文件内移动”的粒度来选择。
gg跳转到文件第一行,G跳转到文件最后一行;Ctrl + f向下翻页,Ctrl + b向上翻页;:n跳转到第 n 行,比如:120直接跳到第 120 行;%在匹配的括号对之间跳转,比如光标在(上按%,它会跳到配对的)上;*在 vim 中搜索光标所在的单词并跳转到下一处,#向前搜索当前单词。
日常排查日志文件时,我基本不用鼠标滚轮,就靠 G 跳到文件尾部看最新错误,再配合 :行号 精确跳转。如果你知道某段代码大概在第几行,直接输冒号加行号,比肉眼找快得多。熟练之后,这些跳转会成为肌肉记忆,手几乎不离键盘。
4.2 搜索与匹配高亮
在正常模式下按 /,输入关键词再回车,vi 会向下搜索;按 ? 是向上搜索。搜索到之后按 n 跳到下一个匹配,N 跳到上一个匹配。这个逻辑和浏览器里的 Ctrl+F 完全不同,但习惯之后很方便,因为你不需要弹窗确认,直接连续按 n 就能巡览全文。
搜索时要注意特殊字符的转义问题。比如想搜索 https://example.com 里的斜杠,直接输入 /https:// 会出问题,因为 / 是搜索命令的边界符号,需要这样写:/https:\/\/。反斜杠在这里是转义符,告诉 vi 后面的 / 是普通字符。如果记不住转义规则,最省事的办法是打开搜索高亮,用 / 输入一段唯一的普通文字,再配合 n 慢慢跳。
vim 里经常搜索之后高亮一直留在屏幕上,看着碍眼。想取消高亮,执行 :noh 或 :nohlsearch,它只取消当前的高亮显示,不会影响搜索时的跳转。如果是完整版 vim,可以设置 set nohlsearch,以后搜索完就不自动高亮了。
4.3 用命令行模式完成批量替换
vi 里最强大但最容易被忽略的命令是 :s(substitute),它能批量替换文本。基本写法是:
vim复制:%s/旧文本/新文本/g
拆开看:% 表示全文范围,s 是替换命令,g 是全局替换,也就是每一行中所有符合条件的地方都替换,而不是只替换每行第一个匹配。如果不写 %,默认只作用于当前行。如果不写 g,每行只替换第一次出现的匹配。所以:
:s/foo/bar/只替换当前行第一个 foo;:%s/foo/bar/g替换全文所有 foo;:1,30s/foo/bar/g只替换第 1 到第 30 行范围内的 foo;:.,$s/foo/bar/g从当前行到文件结尾范围内替换。
这里还要说一个容易踩的坑:替换命令里的 / 分隔符。如果你想替换的文本本身就包含 /,比如把路径 /usr/local 替换为 /opt/app,直接写 :%s//usr/local//opt/app/g 会乱套,斜杠把命令结构打散了。解决办法是在命令里改用其他分隔符,vi 允许你用 # 或 @ 替代 /:
vim复制:%s#/usr/local#/opt/app#g
同样的道理适用于替换网址、日志路径等含斜杠的内容。很多人初次使用替换命令会在这上面卡很久,其实把分隔符换掉就立刻解决了。
5. 多文件编辑和最小化配置
5.1 缓冲区和多文件切换
vi 可以同时打开多个文件,启动时写成:
bash复制vi file1.txt file2.txt
文件会按顺序加载到缓冲区中,当前只会显示第一个文件。在正常模式下输入 :n 并回车,切换到下一个文件;:prev 回退到上一个文件;:buffers 或 vim 里的 :ls 可以查看当前打开了哪些文件;:b 2 直接切到编号为 2 的缓冲区。这个机制在做跨文件编辑的时候非常有用,比如你改一个配置项要同时参考样例文件和正式文件,不需要切窗口。
还有一种是分屏显示,vim 支持 :split 上下分屏、:vsplit 左右分屏,然后按 Ctrl + w 后跟上方向键可以切换激活窗口。我不建议新手一上来就玩分屏,先掌握缓冲区切换就够用了。但如果你的任务是同时对照两个文件的差异,分屏确实比来回切换更直观。用鼠标选中复制的时候要格外注意,分屏窗口之间拖动内容很容易误操作,老实用 y 复制再 p 粘贴更稳妥。
5.2 一个不过度但够用的 .vimrc
很多人学习 vi 之后的第一步是找一份别人的 .vimrc,粘贴一堆看不懂的配置,结果打开文件各种报错。我建议配置从最小开始,逐步加。下面这份是我认为“普通人足够用”的基础配置:
vim复制set number " 显示行号
set relativenumber " 相对行号,方便移动
set autoindent " 自动缩进
set tabstop=4 " Tab 显示为 4 个空格宽度
set shiftwidth=4 " 缩进宽度为 4 个空格
set expandtab " 输入 Tab 时转换成空格
set ignorecase " 搜索时忽略大小写
set smartcase " 如果搜索含大写则区分大小写
set incsearch " 输入搜索关键词时实时高亮
set hlsearch " 搜索后保留高亮
set cursorline " 高亮当前行
set paste " 粘贴时不自动缩进(粘贴代码时常用)
syntax on " 开启语法高亮
这些配置并不是越多越好。比如 set paste 开启之后,自动缩进会被禁用,平时编辑代码反而会有点别扭,所以我习惯在需要粘贴外部内容时才临时开启,用完就关闭。配置文件的生效过程是:每次执行 vi 时读取 ~/.vimrc。你改完配置想立刻验证效果,比如刚加了 set number,不用重启 vi,在 vi 里直接执行 :source ~/.vimrc,配置就会立即生效。
5.3 别人的配置不要盲目照抄
网上一搜能搜到一堆被称为“IDE 级”的 vim 配置,什么代码补全、文件树、git 集成、模糊搜索全都塞进去。这些功能确实帅,但前提是你已经熟练掌握了原生 vi 操作。我见过太多同事把别人配置一贴,结果插件依赖没装好,打开 vi 就报错,连文件都改不了,最后又回到记事本。
真正有价值的做法是先保持纯 vi 工作两周,把 hjkl、i、dd、yy、/、:wq 这些练到不需要思考,再考虑少量插件。插件管理器我常用 vim-plug,安装方式看官方文档就行,但注意 CentOS 等系统上默认的 vim 可能是 tiny 版本,不支持插件,得先安装完整 vim。安装插件的核心原则是“解决实际问题”,比如你经常在两个项目之间切换文件才需要模糊搜索插件,否则默认的文件切换命令已经够快。
6. 常见报错与中文环境问题
6.1 退出 vi 的常见坑
标题热搜词里有“退出vi编辑模式”,这说明很多人栽在这个最基本的操作上。我整理了几种最常见的退出场景和命令:
| 场景 | 正确命令 | 解释 |
|---|---|---|
| 修改完要保存退出 | :wq |
写盘并退出 |
| 没修改想直接退出 | :q |
直接退出 |
| 改了内容但想放弃 | :q! |
强制退出,不保存 |
| 怎么按都没反应 | Esc 后 :q! |
先回到正常模式,再退出 |
误入了 : 命令状态 |
按 Esc |
取消命令行输入 |
如果你的 vi 确实显示 -- INSERT --,说明还在插入模式,直接按 Esc 退出插入模式,就可以输入 : 命令了。如果按 Esc 没反应,可能是终端把 Esc 吞掉了,试试 Ctrl + [. 这在某些终端模拟器里比较常见,特别是把 Esc 绑定到其他功能的工具。
还有一种情况,是你在命令行底部打了一个错误的命令,比如 :wqq,vi 会提示 E488: Trailing characters 这样的错误。别慌,先按 Esc 取消,重新输入正确的 :wq。这里有一点老手才明白的道理:q 退出不了的常见原因是有未保存修改或者还有窗口没有关闭,系统会提示 E37: No write since last change,这时候要么用 :wq 保存退出,要么用 :q! 强制丢弃修改。
6.2 终端中文乱码和 locale
网上搜“vi”相关关键词的时候,经常能看到“error while installing Chinese simplified language pack for vi”这种报错。这里要先澄清:vi 本身并不需要安装语言包,vim 的菜单帮助基本都用英文。你在其他软件里安装简体中文语言包时出现错误,问题通常不在 vi,而在系统的 locale 环境或脚本执行权限上。
检查系统是否支持中文字符集,在终端执行:
bash复制locale -a | grep zh_CN
如果没有输出,说明系统没装中文语言环境;如果有 zh_CN.UTF-8,说明支持。vi 里中文乱码通常是终端编码和文件编码不一致造成的,比如文件是 UTF-8 编码,但终端默认用 latin1 或 GBK 显示。在 vim 里输入:
vim复制:set encoding=utf-8
:set fileencodings=utf-8,gbk,gb2312
再打开文件,中文大概率能正常显示。如果你看到的是 garbled 一样的乱码,先确认文件本身的编码,再调整终端的字符集。服务器上临时处理中文文件时,我一般用 file -i 文件名 查看编码,再决定用什么方式打开。
6.3 误删内容后的恢复
在 vi 里误删文件内容、误退出,这个问题几乎所有人都遇到过。先说最简单的:在正常模式下误删了某一行,立刻按 u 撤销回来。如果你删除后又做了其他操作,可以连续按 u 回退到删除之前。如果你已经保存退出,那就没法用 u 恢复了,除非 vim 配置了持久化撤销,默认没开。
还有个方向是交换文件。vi 会在编辑时生成一个名为 .文件名.swp 的交换文件,用来保存未写入的改动。如果 vi 异常退出,比如终端被强制关闭,下次打开时会看到 Swap file 报错。这时有两种选择:如果是你自己上次的操作残留,确认没在用就按 d 删除交换文件继续编辑;如果怀疑有另一个进程正打开着这个文件,那就先别乱动,看看是不是其他终端在编辑。这个提示看着吓人,其实很常见,记住别上来就删,先确认没有其他编辑器占用。
7. 关于 vi 的几条个人建议
说实话,vi 的学习曲线在刚上手时确实有点陡,但跨过去之后的收益是长久的。我第一次在服务器上改配置时也手忙脚乱,按 Esc 按到键盘冒火星,最后还被 :wq 和 :q! 搞混,直接把一个小时的修改全丢了。后来我在自己电脑上刻意把所有文本编辑都切到 vim,强迫自己不用鼠标,大概一周之后,手指就养成了条件反射:看到 j 就知道往下,看到 i 就知道插入,看到 Esc 就知道回正常模式。
如果再给我一次学习的机会,我会按这样的顺序来消化:先会用 vi 打开文件、输入内容、保存退出,这是“能干活”;再练移动和删除,让手能跟上眼睛,这是“有效率”;接着研究搜索替换和宏,让重复劳动变少,这是“会偷懒”;最后才碰配置和插件。不要贪多,每层练扎实了再进行下一层。
最后一个实用技巧:如果你有多个服务器要管理,在最常用的机器上把 .vimrc 备份到 Git 仓库,下次新装系统直接拉下来,配置文件一行不用重新手写。vi 这东西看起来很旧,但它那句“编辑器之神”的外号,在今天依然不是虚的。
