1. 认识 vim/vi:先搞清楚它为什么是学习 Linux 绕不开的一道坎
学习 Linux,无论你是刚入行的运维新人,还是在做嵌入式开发、后端服务、云计算相关的工作,迟早会撞上一个叫 vim(或者它的老前辈 vi)的东西。我的一个习惯是:只要 SSH 登录到服务器,默认编辑器几乎必然是 vim,跑完 apt 或 yum 安装后要用 visudo 改配置,Cron 任务用 crontab -e 打开,Git 提交信息也要在 vim 里写。你可以在不同发行版上看到 nano、emacs、gedit 这些编辑器,但它们的出现频率远远比不上 vim,因为 vim 是几乎所有 Linux 系统默认预装的编辑器,没有图形界面也能流畅工作,这个“没有图形界面也能用”的能力,在服务器运维、嵌入式开发和容器环境中简直是刚需。
如果你在网上搜索 Linux 相关的内容,几乎任何一个教程网站、面试题集锦、技术博客都会提到 vim。热搜词里出现的“linux常用命令大全”“linux面试题”这些词,背后几乎都绕不开 vim 的基本操作。因为 vim 的操作思路和 Windows 下常用的记事本、IDE 里的编辑器完全不同,你刚打开 vim 时,可能会觉得它“什么也不能输入”,然后就会一头雾水。其实这正是 vim 的核心设计:一个模态编辑器,在不同场景下通过不同模式来完成编辑工作。这种设计在一开始会让人产生强烈的挫败感,但一旦习惯了,你可能会发现它在纯键盘操作下比绝大多数图形编辑器更高效。
这一篇内容,我就会按照“为什么难懂—模式怎么理解—高频操作怎么记—配置怎么调—插件生态怎么用—常见坑怎么避”的顺序,把 vim/vi 这块硬骨头一点点拆开。不管你是纯新手,还是已经用了几个月但想系统补一遍的老手,都应该能在其中找到有价值的信息,尤其是那些平时记不住、容易弄混的命令,我会尽量用场景化的方式讲清楚,而不是简单地堆出一个命令大全。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心设计理念:模态编辑到底是什么,理解这个才能学会 vim
2.1 为什么 vim 不让你直接打字,它的模式逻辑到底是什么
第一次打开 vim 的人,十个里有九个会问:“怎么我敲的字都不显示在屏幕上?”这不是你的键盘坏了,而是 vim 默认处于“命令模式(Normal Mode)”。在这个模式里,你按下的字母不是用来输入的,而是用来执行操作的,j 代表向下移动一行,w 代表跳到下一个单词开头,d 代表删除,这些字符本身并不输入到文件内容里。只有当你按下 i、a、o 等进入“插入模式(Insert Mode)”后,键盘上的普通字符才会被输入到文本中。
这种“命令模式 + 插入模式”分离的设计,是现代很多编辑器插件(比如 VSCode 的 Vim 插件)都在模仿的,因为它能解放你的右手:不用频繁在键盘和鼠标之间切换,也不需要用组合键来完成高频操作。在图形编辑器里,你想要把光标移动到行尾,可能要用鼠标点击,或者按住 Ctrl 加方向键;在 vim 里,命令模式下一个 $ 就直接到行尾,一次按键完成一个动作,这就是所谓“模态”带来的效率优势。
新手最容易犯的错误,就是打开 vim 以后疯狂按 i 发现没有反应,或者在一个文件里敲了一堆字母,然后发现自己把文件内容搞乱了。这是因为在命令模式下,每个按键都会触发一个命令,比如你按了 x,光标下的字符就被删掉了。所以在初学阶段,你要时刻问自己:“我现在在哪个模式?”这个意识一旦建立起来,vim 就不再神秘,后续的一切命令学习都会顺畅很多。
2.2 vim 的三种核心模式与切换方法:命令模式、插入模式、末行模式
严格来说,vim 有十几种模式,但初学者只需要掌握三种就够了:命令模式、插入模式、末行模式(也叫底线命令模式、命令行模式)。它们之间的切换关系,可以用一句话概括:打开文件默认进入命令模式,按 i 进入插入模式,按 Esc 回到命令模式,在命令模式按 : 进入末行模式,执行完命令后 vim 会自动回到命令模式。
这三个模式的关系如下:
- 命令模式:所有移动、删除、复制、粘贴、撤销操作都在这执行,也是进入其他模式的起点。
- 插入模式:真正的文本输入模式,你敲什么字符就输入什么字符。
- 末行模式:执行保存、退出、查找替换、显示行号、设置环境等命令的模式,所有命令以
:开头。
切换操作其实非常容易记:想输入,按 i;想执行命令,按 Esc 回到命令模式;想保存退出,按 Esc 后再按 :,输入 wq 回车。这个节奏几乎构成了 vim 操作的底层肌肉记忆。我见过很多教程把模式切换画成很复杂的图,但实际上你只需要死记这几个键,并在日常操作中刻意练习几次,就能形成条件反射。相比之下,如果你一开始就去研究什么“可视模式”“块选择模式”“宏录制模式”,很容易信息过载,反而连最基本的编辑都做不好。
2.3 命令模式里的移动操作:方向键之外,为什么高手都用 h/j/k/l
在命令模式里,移动光标是最基础的操作,也是新手最容易忽略其价值的部分。方向键在 vim 里确实可以用,但在很多老式终端、远程连接环境或者特定键盘布局下,方向键的响应并不稳定,而且使用方向键需要把手从字母区挪开,这会打破连续操作的节奏。所以 vim 沿用了几十年的经典设计:用 h、j、k、l 四个字母代表左、下、上、右,这样手始终保持在键盘核心区域。
理解了这一点之后,建议你顺手把另一组常用移动命令也一起记住,它们能帮你快速定位到想要的位置:
gg:跳到文件第一行G:跳到文件最后一行0:跳到当前行的行首(包含缩进空格开头的第一个字符处)^:跳到当前行第一个非空字符前$:跳到当前行行尾w:跳到下一个单词开头b:跳到上一个单词开头Ctrl + d:向下翻半屏Ctrl + u:向上翻半屏Ctrl + f:向下翻一屏Ctrl + b:向上翻一屏%:跳到匹配的括号处,这个在检查代码时非常有用
你并不需要一次性全部背下来,可以先从 gg、G、0、$ 开始,遇到具体场景再补 w、b、% 这些。有一个很实的建议:每次打开一个非生产环境的配置文件,可以故意不用鼠标和方向键,只用这些快捷键来回跳几遍,大约一两天你就会形成肌肉记忆,之后再用方向键反而会觉得慢。
2.4 插入模式的高级进入方式:不想从头敲,就用 i/a/o 和它们的变体
i 是进入插入模式最常用、最基础的按键,代表“在当前光标位置之前插入”。但实际编辑文件时,你经常希望光标直接跳到某一行行尾继续写,或者另起一行写新内容,这时候如果用 i 然后再按 End 或 $ 再切换到插入模式,就会多几步操作。vim 为此设计了多个进入插入模式的入口:
a:在当前光标位置之后插入A:跳到行尾并进入插入模式I:跳到行首并进入插入模式o:在当前行下方新开一行并进入插入模式O:在当前行上方新开一行并进入插入模式s:删除当前光标下的字符并进入插入模式S:清空当前行内容并进入插入模式cw:删除当前单词并进入插入模式cc:清空当前行并进入插入模式
这些变体与其说是多个命令,不如说是“编辑意图 + 插入模式”的组合。比如你想在某一行后面追加一段说明,直接用 A,一步到位;你发现当前行写错了想重写,用 S 或者 cc 直接清空重来;你想改一个单词而不用先删除再插入,用 cw 一键搞定。把这几个命令用熟之后,你会发现写配置文件的效率会明显提升,因为每次“移动光标 + 切换模式 + 输入文本 + 切换回来”的操作链被大大缩短了。
3. 高频操作实战:日常编辑里用得最多的命令,按场景整理成速查
3.1 编辑与删除操作:d、x、r、u 这些键怎么组合出强大的编辑效果
编辑操作是 vim 里最核心的功能块。这里有一个非常关键的概念:vim 的命令语法大多遵循“动作 + 范围/对象”的组合逻辑。举例来说,d 代表删除,但单独按 d 是没有作用的,你必须告诉它删除的目标:dw 删除从光标位置到单词末尾,dd 删除整行,d$ 删除从光标位置到行尾,d0 删除从行首到光标前一位置。一旦理解了“动词 + 名词”的组合方式,你会发现自己能举一反三地构造出大量命令,而不是死记硬背每一个命令。
常用编辑操作,按我的使用频率排序如下:
x:删除当前光标下的字符,等价于按 Delete 键dd:删除当前行,并把它保存在寄存器里,可以理解为“剪切”3dd:从当前行开始连续删除 3 行dw:删除当前单词到词尾d$或D:删除光标位置到行尾d0:删除光标位置到行首r+ 字符:把当前光标下的字符替换成你按的那个字符R:进入替换模式,连续替换后面的字符直到按 Escu:撤销上一步操作Ctrl + r:反撤销(重做).:重复上一次操作,这个键极其强大,可以用来重复删除、重复上一次插入的文本
关于删除,很多新手最怕的是“我删错了一整行怎么办”。这个场景不要太慌,vim 的 u 撤销功能几乎可以无条件回退你的上一步操作,甚至按 u 多次可以连续回退。再加上 Ctrl + r 可以恢复你撤销掉的内容,所以只要你没有保存并关闭文件,大部分误操作都可以救回来。还有一个细节:dd 剪切的内容存在寄存器里,你可以用 p 粘贴到别处,这其实就是“剪切 + 粘贴”在工作流中的典型用法,和其他编辑器的 Ctrl+X 逻辑是一样的。
3.2 复制、粘贴与可视化选择:从普通编辑到块操作,一步到位
复制粘贴在 vim 里的表达方式很容易让人迷惑,因为在命令模式下,y 才是复制(yank),p 才是粘贴(put)。它们和日常使用的 Ctrl+C/Ctrl+V 完全不同,但在 vim 的语境里理解起来不算难:y 和 d 的用法基本对称,你只需要把 y 当成“复制”动词,配上各种范围即可。
yy:复制当前这一行3yy:复制从当前行开始往下的 3 行yw:复制当前单词y$:复制从光标位置到行尾的所有内容p:粘贴到当前光标所在位置之后(如果在行命令后使用,则粘贴到下一行)P:粘贴到当前光标所在位置之前(如果在行命令后使用,则粘贴到上一行)
如果你想复制的不只是整行、单词或者块,而是一段不规则的文本,那就需要用到“可视模式”了。在命令模式下按 v 进入可视模式,然后移动光标选择文本,选好后按 y 复制、按 d 删除、按 > 或 < 缩进,按 Esc 退出可视模式。按 V 则是按行选择,适合整段操作;按 Ctrl + v 进入可视块模式,可以纵向选择多列文本,这在批量注释、批量删除某些列时极为好用。比如你有一段代码,想要在所有行前面加上 # 注释符,可以按 Ctrl + v 选择这几行,按 I 输入 #,然后按 Esc,vim 会一次性在所有选中的行首插入这个字符。这类操作是图形编辑器很难做到这么轻快的。
3.3 查找与替换:不会这招,改配置文件时你只能靠肉眼找
配置文件动辄几百上千行,用眼睛一行行扫去找某个参数,效率太低了。vim 的查找和替换功能就是为此准备的。在命令模式下按 /,然后输入你要查找的内容并回车,vim 会从光标位置向后查找,按 n 跳到下一个匹配项,按 N 跳到上一个匹配项。如果你想向前查找,用 ? 代替 /。查找时还可以使用正则表达式,比如 /^# 能快速匹配所有以 # 开头的行,这在查看配置文件的注释部分时非常好用。
替换操作比查找更复杂一点,它通常是在末行模式下完成的。最常见的一条命令是:
vim复制:%s/old/new/g
这条命令的拆解逻辑是:% 代表全文范围,s 是 substitute(替换)的缩写,old 是要查找的旧内容,new 是替换成的新内容,g 是全局替换,表示每一行所有出现的位置都替换,而不是只替换每行第一次匹配到的位置。如果你只想在某几行范围内替换,把 % 换成行号即可,比如:
vim复制:1,10s/old/new/g
表示在第 1 到第 10 行之间替换。还有一个很实用的变体是加上 c 标志,例如 :%s/old/new/gc,这样每次替换前 vim 都会询问你是否确认,防止批量替换时误伤内容。我记得有一次我打算把配置文件里所有 server 替换成 client,结果发现注释里也有很多 server 字样,如果没有加 c 确认,整个配置就废了。所以涉及批量替换时,我建议你先用 :%s/old/new/gc 跑一遍,确认无误后再决定要不要全局强制。
3.4 多文件操作与切换:一次编辑多个配置文件的必备技能
日常运维中,一个改动往往牵涉多个文件,比如改 Nginx 配置时你可能需要同时看 nginx.conf 和某个站点配置文件,改代码时你需要同时看接口定义和调用方实现。vim 支持在同一个窗口打开多个文件,也支持分屏显示。
第一种方式:启动时直接打开多个文件。
bash复制vim file1.conf file2.conf
此时 vim 打开的是 file1.conf,你需要用 :n 切换到下一个文件,用 :N 或者 :prev 切换到上一个文件,用 :buffers 或 :ls 列出所有已打开的文件,用 :buffer 编号 跳转到指定文件。这种方式适合一次会话里顺序查看几个文件。
第二种方式:分屏显示,这在我的实际使用中更加常用。
vim复制:split file2.conf " 水平分屏
:vsplit file2.conf " 垂直分屏
Ctrl + w + w " 切换到另一个分屏
Ctrl + w + h/j/k/l " 按方向切换分屏
分屏之后,你可以一边看着 Nginx 主配置,一边编辑被 include 的子配置,改完一个文件后按 :wq 保存退出当前分屏。这个操作逻辑和 IDE 里的分割视图几乎一样,但 vim 是通过纯键盘完成这一切的,在某些无图形界面的服务器上,这是唯一能实现“多文件对照编辑”的方案。我强烈建议你在学习 vim 的早期就养成 :vsplit 的习惯,因为对照编辑的场景在真实工作中出现得太频繁了。
3.5 快速跳转:数字 + 命令的组合,减少无谓的移动
vim 的一个强大特性是几乎所有命令都可以和数字连用,表示“执行多少次”。这个特性在你需要连续移动或操作多行时特别有用。比如 5j 表示向下方移动 5 行,2w 表示向前跳 2 个单词,3dd 表示删除 3 行,2yy 表示复制 2 行,10G 表示跳到第 10 行。
这个“数字 + 操作符”的逻辑看似简单,却能让你在长文件里快速定位并完成批量操作。举个例子:你打开一个配置文件,想删除第 20 到 25 行的内容,可以先输入 20G 跳到第 20 行,再输入 6dd 删除 6 行;你想把第 100 行到第 120 行内容复制到文件末尾,可以先 100G 跳转,再 21yy 复制,然后 G 跳到末尾,最后 p 粘贴。这一连串操作完全不需要滚动屏幕,非常流畅。
除此之外,Ctrl + o 和 Ctrl + i 是跳转到“上一个位置”和“下一个位置”,这类似浏览器里的前进后退。当你在多个文件、多个分屏之间来回跳转时,这两个快捷键能帮你快速回到之前的编辑现场,不必重新找位置。实践里我觉得这是被很多人忽略但价值极高的功能。
4. 进阶配置:打造属于自己的 .vimrc,让 vim 更适合干活
4.1 为什么建议第一件事就配置 .vimrc,而不是裸用 vim
先回答一个常见问题:“我到底要不要一上来就花时间配置 vim?”我的看法是:如果你只是偶尔在服务器上改个文件,裸 vim 也够用;但如果你把 vim 当作主力编辑器,哪怕只是主力编辑器之一,也一定要配置 .vimrc。原因很简单:默认 vim 没开启语法高亮、没有显示行号、缩进策略也比较古老,编辑体验非常“朴素”,甚至会让你觉得 vim 是一款很落后的软件。但实际上这些体验完全可以通过几行配置改善。
.vimrc 是 vim 的配置文件名,位于你的用户主目录下(~/.vimrc)。它是纯文本文件,每一行是一条配置命令。vim 启动时会自动读取并执行这个文件里的内容。这台机器上的所有用户都可以有自己的独立 .vimrc,互不干扰。如果你有 root 权限,也可以配置 /etc/vim/vimrc 或 /etc/vimrc 来影响所有用户,但一般情况下我不建议改全局配置,因为每个人的编辑习惯不同,把个人偏好写进全局文件反而容易引发混乱。
4.2 基础配置清单:行号、语法高亮、缩进、编码、搜索,逐项讲解
下面分享一份我常用的 .vimrc 基础配置,每一行都给出注释说明,方便你自己调整:
vim复制" 关闭 vi 兼容模式,启用 vim 扩展功能
set nocompatible
" 显示行号
set number
" 开启语法高亮
syntax on
" 开启文件类型检测,并根据文件类型加载相关插件和缩进
filetype plugin indent on
" 设置缩进宽度为 4 个空格
set shiftwidth=4
set tabstop=4
" 把 Tab 键展开为空格
set expandtab
" 自动缩进,换行后保持上一行的缩进
set autoindent
" 搜索时忽略大小写
set ignorecase
" 搜索时如果包含大写字符,则区分大小写
set smartcase
" 输入搜索内容时,边输入边高亮匹配
set incsearch
" 搜索结果高亮显示
set hlsearch
" 在命令模式按一下 Esc 取消高亮
nnoremap <Esc> :nohlsearch<CR>
" 显示光标所在位置的坐标(行、列)
set ruler
" 编码设置,避免中文乱码
set encoding=utf-8
set fileencodings=utf-8,gbk,utf-16,big5
我来说几个关键配置的理由。set expandtab 是我个人强烈推荐的,因为把 Tab 展开成空格后,不同编辑器打开同一个文件时缩进不会错乱,尤其适合团队协作场景。set smartcase 也非常实用:当你的搜索内容全是小写时,vim 会自动忽略大小写;一旦你在搜索词里输入了大写字母,vim 就会严格区分大小写,这比一遍遍切换忽略大小写选项高效得多。nnoremap <Esc> :nohlsearch<CR> 是取消高亮的快捷键映射,因为执行完搜索后,匹配内容会一直高亮,有些人会觉得很碍眼,这个映射让你按一次 Esc 就清掉高亮。
4.3 使用 Vim-Plug 管理插件,装几款能明显提升效率的插件
vim 的插件生态非常丰富,从文件导航、自动补全、代码格式化到主题配色都有。要安装插件,我推荐使用 Vim-Plug,它比老派的 Pathogen 更干净,支持并行安装和按需加载。
安装 Vim-Plug 的官方命令是:
bash复制curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
安装完成后,在 .vimrc 里声明插件即可。下面是我个人比较常用的插件组合:
vim复制call plug#begin('~/.vim/plugged')
" 文件树浏览
Plug 'preservim/nerdtree'
" 状态栏美化,显示当前分支、文件类型、光标位置等
Plug 'vim-airline/vim-airline'
" 模糊查找文件,类似 IDE 里的 Ctrl+P
Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
Plug 'junegunn/fzf.vim'
" 自动补全,支持 LSP 和异步补全
Plug 'neoclide/coc.nvim', {'branch': 'release'}
" 代码注释插件,按 gcc 注释当前行
Plug 'preservim/nerdcommenter'
" 语法检查
Plug 'dense-analysis/ale'
call plug#end()
配置好之后,重新打开 vim,执行 :PlugInstall 就会自动安装所有插件。这几个插件的定位很清晰:NERDTree 用来快速浏览项目文件,fzf 用来按文件名模糊搜索文件,coc.nvim 负责代码补全和语法提示,ALE 做异步语法检查,airline 只是改善视觉效果。如果你是运维为主,平时不怎么写大段代码,可以先只装 NERDTree 和 fzf,这两个对配置文件的浏览和查找很有帮助;如果你做开发,coc.nvim 会是提升效率的大杀器,它支持 Python、JavaScript、Go、Rust 等多种语言的 LSP 补全。
4.4 自定义快捷键:把最常用的操作映射到顺手的位置
我对 .vimrc 里自定义快捷键一向持“克制”态度,因为默认的 vim 快捷键已经非常成熟,改太多反而会破坏肌肉记忆。但有几个高频操作,映射到不常用的键位或者更顺手的组合键上,确实能提升体验。
举例来说,<leader> 在 vim 里由用户定义的一个前缀键,类似“快捷键的命名空间”,默认是反斜杠 \。我习惯把它改成空格键:
vim复制let mapleader=" "
这样我可以在命令模式快速按空格加某个键来触发自定义操作。比如我把 :w 保存映射成 空格 + s:
vim复制nnoremap <leader>s :w<CR>
把打开 NERDTree 映射成 空格 + n:
vim复制nnoremap <leader>n :NERDTreeToggle<CR>
把快速编辑 .vimrc 映射成 空格 + v:
vim复制nnoremap <leader>v :e $MYVIMRC<CR>
把“撤销搜索高亮”也映射成更简单的 空格 + h:
vim复制nnoremap <leader>h :nohlsearch<CR>
我之所以只映射这几个,是因为它们都是“我几乎每天都会用到、但默认键位不那么顺手”的操作。保存文件你当然可以用 :w,但当你要频繁保存时,空格 + s 会更符合手指的自然位置。需要提醒的是,自定义快捷键要遵循一个原则:不要覆盖 vim 内置的重要功能键位。比如 s 是“替换字符并进入插入模式”,n 是“下一个匹配项”,它们都有各自的用途,除非你用了别的替代方式,否则不建议随意覆盖。
5. 常见问题与排查技巧实录:我在实际使用中踩过的坑
5.1 按 Esc 无法退出插入模式,或者方向键变成 A、B、C、D 的问题
新手用 vim 时最容易遇到的一个问题是:按下方向键,屏幕上没有移动光标,而是出现了 A、B、C、D 这样的字符。原因主要有两种:第一种,终端类型设置不对,导致 vim 无法正确识别方向键;第二种,你当前处于插入模式且终端不支持某些序列,或者是老式 vi 而非 vim。解决办法也很简单:
- 确认你确实在使用 vim 而不是原始 vi,输入
vim --version查看版本; - 在配置文件里设置终端类型:
bash复制export TERM=xterm-256color - 如果方向键完全失效,可以使用
h/j/k/l临时应急,同时检查终端软件的键盘问题。
至于“按 Esc 无法退出插入模式”,通常是因为终端把 Esc 按键当作其他序列解析了,或者你的终端软件使用了特殊的按键捕获。Linux 自带的终端软件一般没有这个问题;Windows 下使用 PuTTY、SecureCRT、Xshell 等工具时偶尔会遇到。可以尝试在终端工具的“终端键盘”设置里关闭“应用光标键模式”,一般是应用模式(Application Cursor Keys)导致的。
5.2 中文乱码或写入 UTF-8 时被转成其他编码,怎么避免
在服务器上编辑中文配置文件是挺常见的事,比如某些业务系统的配置文件里含有中文提示语。如果 vim 显示出来的中文是乱码,或者保存后再打开内容变了,通常都是编码设置问题。vim 里的相关编码参数有 encoding、fileencoding、fileencodings 三个,它们的职责分别是:encoding 是 vim 内部使用的编码,一般设为 UTF-8;fileencoding 是当前文件本身的编码;fileencodings 是打开文件时自动检测编码的顺序列表。
为了更好地兼容中文,我的建议是:
vim复制set encoding=utf-8
set fileencoding=utf-8
set fileencodings=utf-8,gbk,gb18030,utf-16le,big5
这样 vim 打开文件时会按顺序尝试用这些编码去解析,如果第一个 UTF-8 解析失败(比如文件实际是 GBK),就会自动切换到下一个编码。但要注意,如果把一个 GBK 文件保存成 UTF-8,原文件的编码就变了,这时如果你不确定系统里其他程序是否依赖这个文件的原始编码,最好先备份再转换。如果你只是想查看文件内容,不打算修改,可以用 vim 文件路径 打开后,用 :set fileencoding=? 查看当前编码,再决定后续操作。
5.3 粘贴代码时缩进错乱,全被自动缩排成一层叠一层的“锯齿”
这可能是几乎所有用过 vim 的人都踩过的一个大坑:从浏览器、其他编辑器里复制一段代码到 vim,粘贴后每一行前都被塞了莫名其妙的缩进,整个代码结构完全乱套。原因是 vim 在插入模式下会解释粘贴的文本,把它当作你在键盘上逐字输入的内容,自动缩进功能会在每行重新计算缩进层级,于是出现层层叠加的效果。
解决办法非常简单:在粘贴之前,先进入 vim 的“粘贴模式”。
vim复制:set paste
然后再按 i 进入插入模式粘贴,vim 会禁用自动缩进、自动换行等功能,让文本原样进入。粘贴完成后,退出插入模式并执行:
vim复制:set nopaste
恢复正常的编辑模式。这个手动开关在 vim 8 之前是标准操作,虽然 vim 8 增加了“括号粘贴”的改进(也就是支持终端报告的 Bracket Paste Mode),但在很多老版本或者特定终端下仍然不稳。所以我把这个命令记成了条件反射:任何粘贴操作之前,先 :set paste,粘贴完再 :set nopaste。
为了避免每次手工输入太麻烦,还可以在 .vimrc 里用一个快捷键来快速切换粘贴模式:
vim复制set pastetoggle=<F2>
这样在插入模式下按一下 F2,底部就会显示 -- INSERT (paste) --,再按一次就切回正常插入模式,非常顺手。
5.4 swap 文件导致打不开异常退出后的文件,swp 文件怎么处理
vim 在编辑文件时,会在同一个目录下生成一个隐藏的交换文件(swap file),文件名通常是 .文件名.swp。这个文件的目的是防止异常退出时丢失数据,同时防止两个用户同时编辑同一个文件造成冲突。如果你之前没有正常保存退出就断开了连接,或者系统崩溃、SSH 断线,再次打开这个文件时 vim 就会提示:交换文件已存在,并问你如何处理。
正常情况下,你应该按提示选择 E(Recover 的缩写不是这个,但交互界面上会显示 R 是恢复)来恢复未保存的改动,恢复后可以手动删除 .swp 文件,比如:
bash复制rm -f .你的文件名.swp
如果你确认那个 .swp 文件已经没用了,也可以直接删掉再重新打开文件。如果你反过来,怀疑自己的修改没保存完,一定要选 R 或 E 恢复,然后再 :wq 保存。另外,如果经常出现这种异常退出,我建议你检查终端连接是否稳定,或者考虑在 .vimrc 里调整 swap 文件存放目录,比如集中放到 /tmp:
vim复制set directory=/tmp
这样可以避免每个项目目录下都留下 .swp 文件残渣,也方便集中清理。
5.5 用 vim 快速批量修改:把多行注释、多行相同前缀的修改效率拉满
批量修改是 vim 最让人上瘾的场景之一,这里分享三个我在实际工作中用得最多的批量操作套路。
第一个是批量注释或取消注释。如果文件不是代码文件,而是类似 shell 脚本、配置文件,需要在一段内容前统一加 #,可以这样做:按 Ctrl + v 进入可视块模式,用 j/k 选择要操作的行,按 I 进入插入模式并输入 #,再按 Esc,vim 会在所有选中的行行首插入 #。取消注释则要稍微绕一点:按 Ctrl + v 选择这些行的 # 字符,按 x 删除。
第二个是批量修改变量名。比如说你把项目的环境变量名改了,想把文件里所有的 old_var 改成 new_var,使用:
vim复制:%s/\bold_var\b/new_var/g
加 \b 是为了精确匹配整个单词,避免 old_variable 这类前缀相同的内容被误替换。如果只需要在当前行内替换,把 % 去掉::s/old_var/new_var/g。
第三个是使用宏(macro)录制一组操作并重放。比如你有一个任务清单,要把每行都包裹在某个模板中,或对每行执行同样的编辑。按 q 加一个字母(比如 qa)开始录制,接下来你的所有操作都会被记录,直到再按一次 q 结束录制。之后你选中若干行,按 @a 重放宏,或者按 100@a 连续执行 100 次。宏的学习成本略高,但一旦掌握,很多重复劳动都可以被一键化解。
5.6 vim 打开文件时权限不足或文件只读,如何正确保存
另一个常见场景是:你用普通用户打开了一个 root 所有的文件,改到一半发现 :w 保存时提示“E45: 'readonly' option is set”或者“Permission denied”。如果你有 sudo 权限,可以直接用 sudo vim 打开,但如果已经打开文件并做了不少修改,不想重来呢?有两个方案:
方案一:用 :w !sudo tee % 这样可以绕过 vim 写入权限的限制。这条命令的意思是“把当前缓冲区的内容通过 shell 管道交给 sudo tee,由 tee 写入当前文件”。以后如果遇到强制保存,我就用这条命令,它比先退出再用 sudo vim 打开要省事得多。
方案二:把文件复制到可写位置,修改完再放回去,不过这个方案一般只适合紧急情况下,正常不推荐。
需要注意的是,无论用哪种方式,以 sudo 身份写文件都会改变文件属主或权限吗?实际上用 :w !sudo tee % 写入时,文件属主不会自动改变,只是内容被覆盖。如果你希望同时保留原来的属主,通常不需要额外处理,只要你不是用 root 重新创建了文件就可以。
5.7 Linux 面试题里常考的 vim 相关知识点,梳理一下考点
很多公司面试运维或后端岗位时,会考一些 vim 相关的题目。热搜词里也出现了“linux面试题”“linux面试题测试”,说明大家对这个方向的备考很关注。我整理了几个高频考点,方便你自查:
- vi 和 vim 的关系:vim 是 vi 的增强版,vim 支持语法高亮、多级撤销、插件系统等功能,vi 是原始的 ex/vi 编辑器。多数现代发行版里
vi其实是 vim 的一个别名。 - 三种模式的区别及切换方式:命令模式、插入模式、末行模式,
i进入插入模式,Esc 回到命令模式,冒号进入末行模式。 - 保存并退出命令:
:wq、:x、ZZ的区别。:wq和ZZ效果约等同,都是保存并退出;:x只在文件有改动时才写入,类似条件保存。 - 强制退出不保存:
:q!。 - 显示行号、取消行号和跳转到指定行的命令:
:set number、:set nonumber、行号 + G。 - 查找高亮的开关和取消:
:set hlsearch开启,:set nohlsearch取消,或按空格 + h直接清高亮。 - 全局替换命令的格式:
:s/old/new/当前行替换第一个匹配项,:%s/old/new/g全文替换所有匹配项。 - 把 Tab 转换为空格的配置:
set expandtab,反过来用set noexpandtab。
这些考点不难,但都很细节。如果你正在准备面试,建议不只背知识点,还在终端里亲手操作一遍,面试官往往会模拟一个场景,比如“让你在一个日志文件里查找包含 error 的行并统计数量”,你能用 vim 快速回答出来,这比死记命令更有说服力。
6. 不同场景下 vim 的实战方法论
6.1 远程服务器场景:为什么 vim 是运维工作的唯一可靠选择
提到运维,vim 几乎是不可替代的。为什么?因为运维工作大量通过 SSH 登录服务器,不一定有图形界面,就算有也可能因为带宽、延迟等因素不适合用图形编辑器。你在服务器上改 Nginx 配置、改 systemd 服务文件、看日志、调整环境变量,都可能需要快速打开一个文件并修改某一两处内容。vim 的启动速度极快,即使服务器资源紧张,它也能秒开,这是 Nano 之外的编辑器很少能做到的。
在这种场景下,我建议你熟练掌握几个核心技能就够了:打开文件、查找、按行跳转、删除、替换、保存退出,再加一个撤销。这些操作已经能覆盖 90% 的运维任务。你不需要为了炫技去背几百个 vim 命令,真实工作里反复用的就是那些。反而是在极度紧张的生产环境,误操作成本很高,所以我给你的建议是:在非生产环境大胆练习,在生产环境“心要稳、手要准”,尤其避免在没看清文件内容时直接全局替换。
6.2 嵌入式与开发场景:vim 可能不是你唯一的编辑器,但绝不会拖后腿
嵌入式开发或纯后端开发里,你可能平时使用 VSCode、Clion、PyCharm 这类工具,但这些 IDE 内置的终端里也经常要使用 vim 来看日志、改远程服务器上的配置、快速编辑文件。因为你不可能每改一个配置文件都把它下载到本地再上传回去,效率太低,也不符合“在服务器上直接操作”的运维习惯。甚至很多现代 IDE 都提供 vim 插件,比如 VSCode 的 Vim 插件,你可以用 vim 的模式切换和按键习惯在 IDE 里编辑代码,同时还能保留 IDE 的智能补全、重构等功能。
在这种“IDE + vim”混合模式下,你真正需要做的,就是学会命令模式下的移动、删除、复制粘贴、查找替换、可视模式选择,这几个高频操作能让你在写代码时的“选词、改词、删行、调整缩进”等动作变得极快。你会发现,当别人还在用鼠标选中一段再点击删除时,你已经用 daw、ciw 完成了同样的事,这个效率差距在长期编码中会累计得非常明显。
6.3 学习路径建议:从“勉强能用”到“形成肌肉记忆”,需要多少练习
很多人在学习 vim 时容易陷入一个误区:想先把所有命令背完再开始用。这是完全错误的路径。vim 的学习应该是一个“边用边学、不断查漏补缺”的过程。我个人的建议是,分三个阶段推进:
第一阶段,目标:能用 vim 修改远程服务器上的配置文件。你需要掌握的技能是:打开文件、用 i 进入插入模式、用方向键或者 h/j/k/l 移动光标、按 Esc 返回、:wq 保存退出、:q! 取消退出。这些操作熟练后,你已经可以在真实服务器上干活了。
第二阶段,目标:提高编辑效率。你需要掌握的技能是:dd 删除行、yy 复制行、p 粘贴、u 撤销、/ 查找、:s 替换、gg/G 快速跳转、Ctrl + d/u 翻半屏。这时候你编辑长文件的速度已经超过用鼠标滚动的方式了。
第三阶段,目标:形成肌肉记忆和个性化配置。你需要掌握的是:可视模式、宏录制、分屏、多文件切换、.vimrc 配置、插件安装、正则替换。到这个阶段,vim 已经不只是“工具”,而是你的创作环境。你可以花时间研究怎么用 vim 写代码、做笔记、甚至管理任务清单。
关于具体练习量,我无法给出一个精确到小时的标准,但我观察下来,大多数人只要坚持在真实环境中用 vim 代替其他编辑器,大约一到两周就能超越新手期的挣扎,之后随着使用频率增加,肌肉记忆会自然形成。千万不要因为一开始的挫败感而放弃,因为跨过这个门槛之后的体验,和一开始是完全不同的。
7. 我的日常 vim 工作流参考
写到最后,我分享一下我目前在用的 vim 工作流,不是让你照搬,而是提供一个可参考的方向。我的 .vimrc 核心配置在前面已经列过了,这里说一下我平时怎么组织事情。
我打开一个项目文件的第一件事,通常是在 .vimrc 里配置好的 NERDTree 文件树里浏览项目结构,或者用 fzf 快速模糊查找文件名。找到目标文件后,用 vim 打开,开发时依赖 coc.nvim 做补全和语法错误提示,ALE 在后台做异步 lint,发现问题后用 :ALEFix 自动修复格式问题。如果要同时修改多个相关文件,我就用 :vsplit 分屏,左右对照。
写代码时,我会大量用到 ciw(change inner word,修改光标所在的单词)、da((删除括号内的内容)、dd、yy、p 这些操作,配合 . 重复命令,很多重复性的修改一两下就完成了。遇到批量操作时,优先想的是能不能用可视块模式一次性搞定,不行再考虑宏。查找替换必须加 c 确认,没确认前绝不动手全局替换,这是我在生产环境里踩过坑之后的底线。
保存和退出方面,命令模式我已经习惯用 空格 + s 保存,用 :x 保存并退出,避免不必要的退出前重复输入。如果临时切到别的文件,就用 Ctrl + o 返回上一个编辑位置,这个动作频率非常高。
最后再分享一个小技巧:如果你发现自己某个操作重复了三遍,就停下来想一想,vim 是不是有更高效的方法。这个习惯能让你从“会 vim”慢慢变成“能用 vim 思考”,也正是在这些微小的优化里,vim 作为长期投资的价值才会慢慢显现。
