Vim 怎么编辑文件:从进入插入模式到保存的完整步骤
Vim 怎么编辑:用 vim 文件名打开文件,按 i 进入插入模式(底部出现 -- INSERT --)再输入,改完按 Esc 回到普通模式,输入 :w 保存、:wq 保存并退出。按 i 没反应或保存报错,多半是模式不对、打开的不是 Vim,或者当前用户没有写权限。
Vim 怎么编辑文件,只需要记住一个循环:vim 文件名 打开文件,按 i 进入插入模式,这时屏幕左下角出现 -- INSERT --,键盘输入的内容才会写进文件;改完按 Esc 回到普通模式,-- INSERT -- 消失;再输入 :w 回车保存,或者 :wq 回车保存并退出。改乱了不想要,按 Esc 后输入 :q! 回车,文件保持原样。下面用一个实际例子走一遍,再逐个解释新手最常遇到的三类问题:按 i 没反应、看不懂底部的提示、保存时报只读或权限错误。
编辑一个文件的六个步骤
例子:在 /etc/hosts 末尾加一条解析 10.20.0.15 bmc-r01,让这台服务器能用名字访问一台 BMC。修改系统文件需要 root 权限,以 root 登录直接执行;用普通账号的,在命令前加 sudo。
- 打开文件。 执行
vim /etc/hosts。打开后先看最底下一行,正常会显示文件名、行数和大小,例如"/etc/hosts" 2L, 158B(L 是行数,B 是字节数,老版本显示为 C)。如果显示的是[New],说明文件名写错了,Vim 打开的是一个不存在的新文件;显示[New DIRECTORY]则是连所在目录都不存在。两种情况都输入:q退出,核对路径后重新打开;如果显示[readonly],说明当前用户没有写权限,先看后文“保存失败”一节,不要急着修改。 - 把光标移到要改的位置。 刚打开时处于普通模式,按键是命令,不会写进文件。用方向键或
hjkl移动;按G直接跳到最后一行,输入/localhost回车跳到第一个 localhost 处,输入:5回车跳到第 5 行。这个例子要在末尾加一行,按G即可。 - 进入插入模式。 在最后一行上按
o:Vim 在下方新开一个空行,光标停在行首,左下角出现-- INSERT --。按哪个键进入插入模式,决定了从哪里开始输入,下一节有对照表。 - 输入内容。 输入
10.20.0.15 bmc-r01。插入模式下可以用退格键删掉刚输错的字符,也可以用方向键移动光标,和普通编辑器一样。 - 回到普通模式。 按
Esc,左下角的-- INSERT --消失。只要还要执行保存、查找、撤销之类的命令,就必须先回到普通模式。 - 保存。 输入
:w回车,底部显示类似"/etc/hosts" 3L, 178B written,说明已经写入磁盘;输入:wq回车是保存并退出,:q!回车是放弃修改退出。
退出 Vim 后确认一下结果:
tail -n 2 /etc/hosts # 看最后两行,新加的一行应在末尾
getent hosts bmc-r01 # 按系统的解析顺序查询,能返回 10.20.0.15 说明生效
/etc/hosts 保存后对新的解析请求立即生效,不需要重启任何服务。其他文件保存后怎么生效,见文末的表格。
i、a、o 选哪个:同一行上的差别
进入插入模式的键有好几个,区别只在于“从哪里开始输入”。假设当前行是 127.0.0.1 localhost,光标停在 localhost 的第一个字母 l 上,按下表中的键后输入 X 再按 Esc,结果分别是:
| 按键 | 从哪里开始输入 | 这一行变成 |
|---|---|---|
i |
光标所在字符的前面 | 127.0.0.1 Xlocalhost |
a |
光标所在字符的后面 | 127.0.0.1 lXocalhost |
I |
行首第一个非空字符前面 | X127.0.0.1 localhost |
A |
行尾 | 127.0.0.1 localhostX |
o |
在下方新开一行 | 原行不变,下一行是 X |
O |
在上方新开一行 | 原行不变,上一行是 X |
s |
先删掉光标处的一个字符 | 127.0.0.1 Xocalhost |
cw |
先删掉从光标到词尾的内容 | 127.0.0.1 X |
R |
进入替换模式,输入的字符逐个覆盖原字符 | 127.0.0.1 Xocalhost,底部显示 -- REPLACE -- |
按改动的类型选键,能少按很多次方向键:
- 改一个值(端口号、开关),把光标放到值的第一个字符上按
cw,直接输入新值。光标停在值的中间时,cw只会替换后半截。IP 地址、路径这类带.、/的值,cw遇到这些符号就停下,要改用大写的cW,它一直替换到下一个空格之前。 - 在行尾补参数,按
A,不用先把光标挪到行尾。 - 新增一行配置,在相关的那一行上按
o,新行紧跟在它下面,层级和上下文都清楚。 - 只换一个字符,不必进入插入模式:按
r再按新字符,例如把0改成1就是r1。
底部的提示分别是什么意思
Vim 用屏幕最下面一行告诉你当前处于什么状态。看懂这一行,大部分“按键没反应”“输入乱了”的问题就有了方向:
| 底部显示 | 当前状态 | 接下来怎么做 |
|---|---|---|
| 什么都没有 | 普通模式,按键都是命令 | 要输入文字先按 i、a、o 等 |
-- INSERT --(中文界面为 -- 插入 --) |
插入模式,输入的内容直接写进文件 | 输入完按 Esc |
-- REPLACE -- |
替换模式,输入会覆盖原有字符;按了 R,或在插入模式下按了键盘上的 Insert 键 |
按 Esc 退出,被覆盖的内容用 u 撤回 |
-- VISUAL --、-- VISUAL LINE --、-- VISUAL BLOCK -- |
可视模式,正在选中文本 | 按 Esc 取消选择 |
-- (insert) -- |
在插入模式下按了 Ctrl+O,临时执行一条普通模式命令 |
执行完会自动回到插入模式 |
recording @q |
按了 q 再按一个字母,正在录制宏 |
再按一次 q 停止录制,对文件没有影响 |
光标在最后一行,行首是 : 或 / |
命令行模式,正在输入命令或查找内容 | 回车执行,Esc 放弃 |
"文件名" [New] 或 [New DIRECTORY] |
文件不存在,打开的是一个新的空文件;后者表示所在目录也不存在 | 核对路径,拼错了就 :q 退出重开 |
"文件名" [readonly] |
对文件没有写权限,或以只读方式打开 | 见“保存失败”一节 |
"文件名" [Permission Denied] |
连读权限都没有,屏幕上是空白 | :q 退出,用有权限的账号重新打开 |
按 i 没反应:按现象逐个排查
“按 i 没反应”其实是好几种不同的情况,先看清现象再处理:
| 现象 | 原因 | 处理 |
|---|---|---|
按 i 后底部没有任何提示,但接着输入的字母确实出现在文件里;或者在插入模式下按方向键,冒出 A、B、C、D 和空行 |
用 vi 命令打开、系统里只装了精简版 vim-tiny(Debian、Ubuntu 最小安装常见),它以 vi 兼容方式运行:不显示模式提示,插入模式下的方向键也不能用 |
其实已经在插入模式,照常输入;要移动光标先按 Esc 回到普通模式。输入 :set showmode 可以打开提示,彻底解决就安装完整版 apt install vim |
按 i 后文件里多出一个字母 i |
本来就在插入模式 | 按 Esc,再按 u 撤销多出来的字符 |
底部出现 Entering Ex mode. Type "visual" to go to Normal mode.,之后输入的内容只在底部回显 |
在普通模式下误按了大写 Q,进入了 Ex 模式 |
输入 visual 回车,回到普通模式 |
按 i 后底部提示 E21: Cannot make changes, 'modifiable' is off |
用 vim -M 打开,或者当前窗口是目录列表、帮助文档,不允许修改 |
确认打开的是文件本身;确实要改,执行 :set modifiable |
| 按什么键屏幕都不动 | 按过 Ctrl+S,终端暂停了输出;或者 SSH 连接已经断开 |
先按 Ctrl+Q 恢复;还不动就是连接断了,依次按回车、~、. 断开这个会话,重新登录 |
底部有 ^O Write Out、^X Exit 字样 |
打开的是 nano 而不是 Vim,常见于 crontab -e、visudo |
在 nano 里直接输入即可,Ctrl+O 保存、Ctrl+X 退出;想改用 Vim,执行 export EDITOR=vim,Ubuntu 上的 crontab 也可以用 select-editor 选择 |
底部是 (END) 或一个冒号,只能上下翻页 |
是 less 分页器,例如 systemctl cat、git log、man 的输出 |
按 q 退出,它本来就不能编辑 |
Esc 按了不管用,浏览器反而退出了全屏 |
在网页版的远程控制台里操作,Esc 被浏览器拦截 |
用 Ctrl+[ 代替 Esc,两者在终端里发出的是同一个字符 |
按 : 后底部没有出现冒号,或者输入命令后报 E492: Not an editor command |
输入法处于中文状态,打出的是全角冒号或全角字母 | 切换到英文输入法,按 Esc 后重新输入 |
最后两行在远程控制台和中文系统上特别常见。用 BMC 的网页控制台救机时,键盘事件要经过浏览器、控制台程序再到服务器,Esc、F 键和组合键都可能被中间环节截走,Ctrl+[ 这个替代键值得记住。
保存失败:只读、权限和磁盘
普通用户忘了加 sudo,打开 /etc/hosts 修改后保存,会依次看到这几条提示:
- 打开时底部显示
[readonly]:Vim 检测到当前用户对这个文件没有写权限。 - 按
i开始输入时出现W10: Warning: Changing a readonly file:这只是警告,Vim 仍然允许修改缓冲区里的内容。 - 输入
:w时报E45: 'readonly' option is set (add ! to override):保存被拒绝。 - 按提示改用
:w!:文件属于你自己时(例如你把自己的文件设成了只读),Vim 会写入成功;文件属于 root 时报E212: Can't open file for writing,!绕不过系统权限。
已经改了一大段,不想重来,先把内容存到自己有权限的地方:输入 :w /tmp/hosts.new 回车,退出后执行 sudo cp /tmp/hosts.new /etc/hosts。cp 覆盖已存在的文件时保留目标文件原来的属主和权限,不会把 /etc/hosts 变成你的文件。以后编辑系统文件,直接用 sudoedit /etc/hosts(等同于 sudo -e):sudo 先把文件复制成临时文件,用你自己的身份和 ~/.vimrc 打开编辑,退出时再写回原位置,用哪个编辑器由 SUDO_EDITOR、VISUAL 或 EDITOR 环境变量决定。
root 也存不进去,或者报的是别的错误,按下表检查:
| 现象 | 原因 | 检查 | 处理 |
|---|---|---|---|
root 用户 :w 仍报写入失败 |
文件带有不可修改属性(immutable) | lsattr /etc/hosts,属性里有 i |
chattr -i /etc/hosts 后再保存,需要时改完再加回去;不是你们自己设置的,要排查是不是被入侵后有人锁定了文件 |
报 E212,打开时底部显示 [New DIRECTORY] |
文件所在的目录不存在,多半是路径拼错 | 看底部的完整路径 | 路径错了就重开;确实要新建目录,执行 :!mkdir -p %:h 再 :w,%:h 表示当前文件所在的目录 |
| root 保存失败,同一分区上的其他文件也写不进去 | 文件系统被挂载为只读,常见于磁盘出错后内核自动改成只读 | findmnt -no OPTIONS / 的输出里有 ro;dmesg 里有 Remounting filesystem read-only 一类的记录 |
先查清磁盘和文件系统错误,不要直接 remount 成读写继续写入 |
报 E514: Write error (file system full?) |
磁盘或分区写满 | df -h /etc;空间还有但仍失败时看 df -i,可能是 inode 用完 |
不要 :q!,先 :w /dev/shm/hosts.tmp 把内容存进内存盘,清理空间后再保存原文件 |
改错了怎么退回
在保存之前,Vim 能帮你撤回;保存并退出之后,就只能靠备份了。
- 撤销与重做:普通模式下按
u撤销上一步,可以连续按;撤销过头了按Ctrl+r重做。 - 保存前看看改了什么:输入
:w !diff % -回车,把当前缓冲区的内容交给 diff,和磁盘上的文件对比,按回车回到编辑界面。改了很多处、不确定有没有误改时,这一步比来回翻页可靠。 - 回到上一次保存时的状态:
:earlier 1f把内容退回到最近一次:w时的样子,适合“保存过一次、之后越改越乱”的情况。 - 全部不要了:
:e!丢弃所有未保存的修改,从磁盘重新载入;:q!直接退出。
Vim 默认在退出后不保留撤销记录,所以改重要配置前先做一份备份:cp -a /etc/hosts /etc/hosts.$(date +%F),-a 连同权限和时间戳一起保留。
保存之后:不同文件的生效方式
保存只是把内容写进磁盘,修改什么时候生效、用什么方式编辑更安全,各类文件不一样:
| 文件 | 推荐的编辑方式 | 保存后要做什么 |
|---|---|---|
/etc/hosts |
直接用 Vim | 立即生效,用 getent hosts 主机名 验证 |
/etc/sudoers 及 /etc/sudoers.d/ 下的文件 |
visudo,想用 Vim 就执行 EDITOR=vim visudo |
visudo 保存时检查语法,有错会问 What now?,按 e 回去修改;不要用 Vim 直接改,写错后所有人都用不了 sudo |
| 计划任务 | crontab -e,不要直接改 /var/spool/cron 下的文件 |
退出时提示 crontab: installing new crontab 即已生效 |
/etc/fstab |
直接用 Vim,改前备份 | findmnt --verify 检查格式,systemctl daemon-reload 让 systemd 重新读取,再 mount -a 试挂载,没有报错再重启 |
| systemd 服务配置 | systemctl edit 服务名,生成单独的覆盖文件 |
编辑器退出后自动重新加载配置,再 systemctl restart 服务名 |
| sshd、nginx 等服务的配置 | 直接用 Vim,改前备份 | 先用 sshd -t、nginx -t 检查语法,通过后再 reload |
fstab 和 sudoers 写错的代价最大:前者可能让服务器开机进入紧急模式、SSH 连不上,后者会让所有人失去 sudo。遇到这种情况只能从本机控制台登录改回来。机房里的服务器可以通过 BMC 的远程控制台操作,在 Toplink DCIM 的 IPMI 远程管理里,VNC 控制台走 BMC 通道,开机自检、紧急模式的命令行都能看到,进去后用本文的方法打开文件、改回、保存即可;遇到 Esc 被浏览器拦截的情况,记得换成 Ctrl+[。
常见问题
Vim 里怎么把整个文件清空重写?
普通模式下按 gg 回到第一行,再按 dG 删除到文件末尾,然后按 i 输入新内容。也可以输入 :%d 回车,效果相同。清空前先确认文件有备份,误删后在保存之前按 u 可以撤回。
编辑时不小心按了 Ctrl+Z,Vim 不见了怎么办?
Ctrl+Z 把 Vim 挂到了后台,没有退出,修改也还在。在终端输入 fg 回车就能回到编辑界面;jobs 命令可以看到后台挂着哪些程序。不要在挂起状态下另开一个 Vim 编辑同一个文件,否则会出现交换文件提示。
只想看文件内容、不想改,用什么打开更安全?
用 view 文件名 或 vim -R 文件名 以只读方式打开,误按 :w 会被拒绝;只是翻看日志,用 less 更合适,按 / 查找、按 q 退出,不会产生任何修改。