Appearance
03|Vim 编辑器
服务器上没有图形界面,SSH 终端里改配置只能靠命令行编辑器。Vim 是几乎所有 Linux 发行版的默认编辑器,但它的操作逻辑和 Notepad、VSCode 这类桌面编辑器截然不同——打开后不能直接打字,得先进入编辑模式。
第一次接触 Vim 的人,通常会卡在两个地方:打开文件后不知道怎么打字、不知道怎么退出。社区里甚至有"如何退出 Vim"被搜索数百万次的梗。本篇从模式机制讲起,依次介绍光标移动、编辑、搜索替换、可视模式、多文件操作和基础配置。
一、模式机制
Vim 的核心设计是三种模式——同一个按键在不同模式下含义完全不同。这是与普通编辑器最大的差异,也是上手最大的门槛。
| 模式 | 进入方式 | 用途 |
|---|---|---|
| 普通模式 | 按 Esc | 移动光标、复制、粘贴、删除、执行命令 |
| 插入模式 | i、a、o、I、A、O | 输入和修改文本 |
| 命令模式 | 普通模式下按 : | 保存、退出、搜索替换、设置选项 |
打开文件后默认处于普通模式,不能直接打字。这是 Vim 与桌面编辑器最大的认知反差。
bash
vim /etc/hosts执行上述命令后,屏幕显示了文件内容,但此时任何字母按键都不会输入字符,而是被解释为命令——按 i 进入插入模式才能开始打字。
救命准则:任何时候都能安全退出
任何时候只要按 Esc,就能回到普通模式。 这是 Vim 操作的安全基准。从普通模式出发,可以执行所有其他操作。
最基础的退出与保存命令:
vim
:w " 保存
:q " 退出
:wq " 保存并退出
:q! " 强制退出,丢弃所有修改
:x " 等同于 :wq
ZZ " 普通模式下按两次大写 Z,等同于 :wq给初学者的安全退出步骤:不论按了什么键导致界面进入了未知状态,先按 Esc,再输入 :q! 回车——一定能退出,且不会保存任何意外修改。
二、光标移动
普通模式下的光标移动键:
| 按键 | 移动方向 |
|---|---|
h j k l | 左 下 上 右 |
gg | 跳到文件开头 |
G | 跳到文件末尾 |
0 | 当前行行首 |
^ | 当前行第一个非空白字符 |
$ | 当前行行尾 |
w | 下一个单词开头 |
b | 上一个单词开头 |
e | 当前/下一个单词结尾 |
% | 在配对的括号 ()、[]、{} 之间跳转 |
h j k l 在键盘上排成一行,熟练之后无需将手离开主键区,效率高于方向键。j 与 k 的方向可以这样记忆:j 形状向下有钩子(下移),k 在键盘上位于 j 上方(上移)。现代终端中方向键通常也能正常工作,初学时使用方向键也可以,熟练后再切换到 hjkl。
跳转到指定行号
vim
:120 " 跳到第 120 行
:$ " 跳到最后一行
120G " 普通模式下输入数字+G 也能跳行排查配置错误时,这个能力非常实用。例如 Nginx 启动失败时输出:
nginx: [emerg] unexpected ";" in /etc/nginx/nginx.conf:42直接 vim /etc/nginx/nginx.conf 打开文件后,输入 :42 即可跳转到出错的行。
三、编辑操作
1. 进入插入模式
从普通模式进入插入模式的方式有多种,各自位置不同:
| 按键 | 进入位置 |
|---|---|
i | 在光标前插入 |
a | 在光标后插入(append) |
I | 跳到当前行行首并插入 |
A | 跳到当前行行尾并插入 |
o | 在下方新建一行并插入 |
O | 在上方新建一行并插入 |
o 与 O 在追加配置行时高频使用:无需先移动到行尾再回车,直接 o 即可在下一行开始输入。
2. 普通模式下的删除与复制
普通模式下,无需进入插入模式即可完成删除、复制、粘贴:
| 命令 | 效果 |
|---|---|
x | 删除光标处字符 |
dd | 删除整行(同时放入剪贴板) |
dw | 删除一个单词 |
d$ | 删除到行尾 |
yy | 复制整行 |
yw | 复制一个单词 |
p | 在光标后粘贴 |
P | 在光标前粘贴 |
u | 撤销上一步 |
Ctrl+r | 重做(取消撤销) |
3. 数字前缀:批量执行
数字前缀可以让命令重复执行指定次数,这是 Vim 效率的核心机制之一:
vim
5dd " 删除连续 5 行
3yy " 复制连续 3 行
10x " 删除 10 个字符
20j " 向下移动 20 行这种 "数字 + 操作" 的组合方式,远比反复按同一个键高效。复制 50 行用 50yy,删除一段大段配置用 100dd,都是一两秒完成。
四、搜索与替换
1. 搜索
普通模式下按 / 进入向下搜索,按 ? 向上搜索:
vim
/listen " 向下搜索 listen
?error " 向上搜索 error跳转到匹配项后:
| 按键 | 作用 |
|---|---|
n | 跳到下一个匹配 |
N | 跳到上一个匹配 |
* | 搜索光标所在的单词 |
查找配置文件中的某个指令(如 listen、server_name、proxy_pass)时,搜索是定位最快的方式。
2. 替换
替换使用 :s 命令,几种常用形态:
vim
:s/old/new/ " 替换当前行的第一个匹配
:s/old/new/g " 替换当前行的所有匹配
:%s/old/new/g " 替换整个文件的所有匹配(% 表示全文)
:%s/old/new/gc " 替换前逐个确认(c = confirm)
:5,10s/old/new/g " 只在第 5 到第 10 行替换修改生产环境配置文件时,涉及 IP、域名、路径的替换应当带 c 参数。全文替换的影响范围远大于手工逐行修改——例如想把 10.0.0.1 替换为新 IP,但配置中还存在 10.0.0.10 这个完全不同的地址,默认的子串匹配会同时替换这两处,导致服务连接到错误的目标。
带 c 的交互式替换会在每次匹配时停下询问:
replace with new (y/n/a/q/l/^E/^Y)?| 按键 | 含义 |
|---|---|
y | 替换当前这一处 |
n | 跳过当前这一处 |
a | 替换所有(剩余的也全部替换) |
q | 退出替换 |
l | 替换当前这一处后退出 |
精确匹配可以加上单词边界,避免误替换:
vim
:%s/\<10.0.0.1\>/192.168.1.1/gc\< 和 \> 是 Vim 正则中的单词边界,确保只匹配独立的 10.0.0.1,不会把 10.0.0.10、10.0.0.100 也匹配进来。
五、可视模式:选中后批量操作
可视模式用于选中一段文本,选中之后再执行删除、复制、替换、注释等批量操作。
| 进入方式 | 选择类型 |
|---|---|
v | 按字符选择 |
V | 按整行选择 |
Ctrl+v | 按列块选择(块可视模式) |
进入可视模式后,使用 hjkl 或方向键扩展选区,然后:
d— 删除选中内容y— 复制选中内容c— 删除并进入插入模式>— 选中行整体右缩进<— 选中行整体左缩进
块可视模式批量注释
块可视模式 Ctrl+v 在批量注释多行时非常实用。下面演示如何把连续 5 行的开头加上 # 注释:
1. 把光标移到要注释的第一行的行首
2. 按 Ctrl+v 进入块可视模式
3. 按 4j 向下选中 5 行(当前行 + 下方 4 行)
4. 按 I(大写),光标跳到选中块的行首
5. 输入 #
6. 按 Esc 两次,所有选中行的开头都加上了 #按 Esc 之后注释才会真正应用到所有行,中间任何时候按错都可以 u 撤销。
取消注释的逆操作:
1. 光标移到第一个 # 上
2. 按 Ctrl+v 进入块可视模式
3. 按 4j 选中下方 5 行的 # 字符
4. 按 d 删除选中块这套操作适合临时注释测试,正式的配置变更仍然建议保留备份文件(cp -a 复制一份),u 撤销并不是可靠的回滚方案——Vim 进程异常退出或意外执行了 :wq 后,撤销历史就丢失了。
六、多文件与分屏
1. 同时打开多个文件
bash
vim nginx.conf default.conf文件之间切换:
vim
:n " 下一个文件
:prev " 上一个文件
:ls " 列出所有打开的 buffer
:b 2 " 切换到编号为 2 的 buffer
:bd " 关闭当前 buffer2. 分屏对照
修改配置时经常需要同时查看两个文件,例如对照默认配置改业务配置:
vim
:sp other.conf " 水平分屏(上下)
:vsp other.conf " 垂直分屏(左右)分屏之间切换光标:
| 按键 | 作用 |
|---|---|
Ctrl+w h/j/k/l | 切换到左/下/上/右窗口 |
Ctrl+w w | 在所有窗口间循环切换 |
Ctrl+w = | 让所有窗口大小相等 |
Ctrl+w q | 关闭当前窗口 |
七、基础配置:~/.vimrc
Vim 的个人配置存放在 ~/.vimrc。服务器场景下的 Vim 配置应当保持简单——配置过于复杂、依赖外部插件,会导致换一台没有该 .vimrc 的机器时无法正常工作。运维场景的目标是"能舒服地修改配置文件",而不是把 Vim 改造成 IDE。
下面是一份适合服务器场景的基础配置:
vim
set number " 显示行号
set tabstop=4 " Tab 显示为 4 个空格的宽度
set shiftwidth=4 " 自动缩进的宽度(>> 和 << 使用)
set expandtab " 输入 Tab 时自动转换为空格
set ignorecase " 搜索时忽略大小写
set smartcase " 搜索内容包含大写字母时,自动切换为区分大小写
set hlsearch " 高亮搜索结果
set incsearch " 输入搜索内容时实时高亮
set ruler " 在状态栏显示光标当前位置(行号、列号)
set showmatch " 输入括号时高亮对应的另一半
syntax on " 启用语法高亮expandtab:避免 Tab 与空格混用
expandtab 这一项需要特别强调——Python 和 YAML 对缩进极度敏感,Tab 与空格混用会直接导致语法错误。修改 Kubernetes YAML、Ansible playbook、Python 脚本时,如果文件中混入 Tab 字符,排查问题时不容易发现是缩进格式问题。expandtab 强制将所有 Tab 输入转换为空格,从根本上避免这一问题。
可以通过 :set list 显式查看不可见字符,确认是否有混入的 Tab:
vim
:set list输出中 Tab 显示为 ^I,空格为正常空白,行尾换行符为 $。
文件类型相关的自动配置
针对不同文件类型自动应用不同的缩进规则:
vim
filetype plugin indent on " 启用文件类型检测和对应的缩进规则
autocmd FileType yaml setlocal ts=2 sts=2 sw=2 expandtab
autocmd FileType python setlocal ts=4 sts=4 sw=4 expandtabYAML 通常用 2 空格缩进,Python PEP 8 规范要求 4 空格,通过文件类型自动切换可以避免手动调整。
延伸学习资源
- Vim 官方教程 vimtutor — 在终端执行
vimtutor即可启动,约 30 分钟系统覆盖基础操作 - Vim 官方文档 :help — 在 Vim 中输入
:help <主题>查阅,例如:help substitute - Vim Adventures — 通过解谜游戏练习 Vim 操作
- Practical Vim, 2nd Edition — Drew Neil 著,深入掌握 Vim 实用技巧的经典书籍