文件编辑器 vi/vim
章节介绍
vi/vim 是 Linux 系统中最经典、最强大的文本编辑器,几乎所有 Linux 发行版都默认安装了它。vim 是 vi 的增强版,提供了更多高级功能和更好的用户体验。掌握 vi/vim 是 Linux 系统管理员和开发人员的必备技能,因为它不仅功能强大,而且在各种环境下都能稳定运行,特别是在没有图形界面的服务器环境中。本教程将详细介绍 vi/vim 的基本模式、常用命令、高级功能、配置文件和最佳实践,帮助你快速上手并熟练使用这一强大的工具。
核心知识点
vi/vim 简介
历史与发展
- vi:由 Bill Joy 于 1976 年开发,是 Unix 系统的标准文本编辑器
- vim:由 Bram Moolenaar 于 1991 年开发,是 vi 的增强版,添加了许多新功能
- vim 的含义:Vi Improved,即改进版的 vi
主要特点
- 模式化编辑:支持多种编辑模式,如命令模式、插入模式、可视模式等
- 强大的命令集:提供丰富的编辑命令,可高效完成各种编辑任务
- 跨平台:可在几乎所有操作系统上运行
- 可扩展性:支持插件系统,可通过插件增强功能
- 轻量级:占用资源少,启动速度快
- 稳定性:在各种环境下都能稳定运行
安装与启动
# 检查是否安装了 vim
which vim
# 安装 vim(Ubuntu/Debian)
sudo apt update
sudo apt install vim
# 安装 vim(CentOS/RHEL)
sudo yum install vim
# 安装 vim(Fedora)
sudo dnf install vim
# 启动 vim
vim
# 启动 vim 并编辑文件
vim file.txt
# 以只读模式打开文件
vim -R file.txt
# 以新文件模式打开
vim -c "set ft=sh" new_script.sh基本模式
命令模式(Normal Mode)
- 进入方式:启动 vim 后默认进入命令模式
- 功能:执行各种编辑命令,如移动光标、删除文本、复制粘贴等
- 常用操作:
- 移动光标:h(左)、j(下)、k(上)、l(右)
- 删除:dd(删除整行)、dw(删除单词)
- 复制:yy(复制整行)、yw(复制单词)
- 粘贴:p(在光标后粘贴)、P(在光标前粘贴)
- 撤销:u
- 重做:Ctrl+r
插入模式(Insert Mode)
- 进入方式:在命令模式下按 i、I、a、A、o、O 等键
- 功能:输入文本
- 退出方式:按 Esc 键返回命令模式
- 常用命令:
- i:在光标前插入
- I:在行首插入
- a:在光标后插入
- A:在行尾插入
- o:在当前行下方新建一行并插入
- O:在当前行上方新建一行并插入
可视模式(Visual Mode)
- 进入方式:在命令模式下按 v、V、Ctrl+v
- 功能:选择文本块
- 退出方式:按 Esc 键返回命令模式
- 常用命令:
- v:进入字符可视模式
- V:进入行可视模式
- Ctrl+v:进入块可视模式
- 选择文本后可执行复制、删除等操作
命令行模式(Command-line Mode)
- 进入方式:在命令模式下按 :、/、? 等键
- 功能:执行保存、退出、搜索、替换等操作
- 退出方式:执行命令后自动返回命令模式
- 常用命令:
- :w:保存文件
- :q:退出
- :wq:保存并退出
- :q!:强制退出不保存
- /pattern:向下搜索
- ?pattern:向上搜索
- :%s/old/new/g:全局替换
光标移动
基本移动
# 字符级移动
h # 向左移动一个字符
j # 向下移动一行
k # 向上移动一行
l # 向右移动一个字符
# 单词级移动
w # 移动到下一个单词的开头
b # 移动到上一个单词的开头
e # 移动到下一个单词的结尾
# 行级移动
0 # 移动到行首
^ # 移动到行首的第一个非空白字符
$ # 移动到行尾
# 段落级移动
{ # 向上移动一个段落
} # 向下移动一个段落
# 屏幕级移动
Ctrl+f # 向下翻一页
Ctrl+b # 向上翻一页
Ctrl+d # 向下翻半页
Ctrl+u # 向上翻半页
# 行号移动
:n # 移动到第 n 行
gg # 移动到文件开头
G # 移动到文件结尾精确移动
# 移动到指定行
:n # 例如 :10 移动到第 10 行
# 移动到匹配的括号
% # 移动到匹配的括号(适用于 ()、[]、{})
# 移动到上次编辑的位置
`` # 两个反引号
# 移动到文件的特定位置
Ctrl+g # 显示当前位置信息
# 示例:移动到第 50 行
:50
# 示例:移动到文件开头
gg
# 示例:移动到文件结尾
G文本编辑
插入文本
# 在光标前插入
i # insert
# 在行首插入
I # Insert
# 在光标后插入
a # append
# 在行尾插入
A # Append
# 在当前行下方新建一行并插入
o # open
# 在当前行上方新建一行并插入
O # Open
# 示例:在光标前插入文本
# 进入命令模式后按 i,输入文本,按 Esc 返回
# 示例:在文件末尾添加新行
G # 移动到文件结尾
o # 新建一行并插入删除文本
# 删除单个字符
x # 删除光标所在字符
X # 删除光标前的字符
# 删除整行
dd # 删除当前行
ndd # 删除从当前行开始的 n 行
# 删除单词
dw # 删除从光标开始到单词结尾
db # 删除从光标开始到单词开头
de # 删除从光标开始到单词结尾(包括单词末尾)
# 删除行内内容
d0 # 删除从光标到行首
d^ # 删除从光标到行首的非空白字符
d$ # 删除从光标到行尾
# 删除到指定位置
dt{char} # 删除到下一个指定字符(不包括该字符)
df{char} # 删除到下一个指定字符(包括该字符)
# 示例:删除当前行
# 进入命令模式后按 dd
# 示例:删除从当前行开始的 5 行
5dd
# 示例:删除从光标到行尾
d$复制与粘贴
# 复制整行
yy # yank
nyy # 复制从当前行开始的 n 行
# 复制单词
yw # 复制从光标开始到单词结尾
yb # 复制从光标开始到单词开头
ye # 复制从光标开始到单词结尾(包括单词末尾)
# 复制行内内容
y0 # 复制从光标到行首
y^ # 复制从光标到行首的非空白字符
y$ # 复制从光标到行尾
# 复制到指定位置
yt{char} # 复制到下一个指定字符(不包括该字符)
yf{char} # 复制到下一个指定字符(包括该字符)
# 粘贴
p # 在光标后粘贴
P # 在光标前粘贴
# 示例:复制当前行并粘贴到下一行
# 进入命令模式后按 yy,然后按 p
# 示例:复制从当前行开始的 3 行并粘贴到文件末尾
3yy # 复制 3 行
G # 移动到文件结尾
p # 粘贴撤销与重做
# 撤销操作
u # undo
# 重做操作
Ctrl+r # redo
# 撤销一行内的所有操作
U # Undo
# 示例:撤销上一个操作
# 进入命令模式后按 u
# 示例:重做被撤销的操作
# 进入命令模式后按 Ctrl+r替换文本
# 替换单个字符
r{char} # 替换光标所在字符
R # 进入替换模式,连续替换多个字符
# 替换命令(命令行模式)
:s/old/new/ # 替换当前行的第一个匹配项
:s/old/new/g # 替换当前行的所有匹配项
:%s/old/new/ # 替换整个文件的第一个匹配项
:%s/old/new/g # 替换整个文件的所有匹配项
:%s/old/new/gc # 替换整个文件的所有匹配项,每次替换前确认
# 示例:替换当前行的第一个 "apple" 为 "orange"
:s/apple/orange/
# 示例:替换整个文件的所有 "apple" 为 "orange"
:%s/apple/orange/g
# 示例:替换整个文件的所有 "apple" 为 "orange",每次替换前确认
:%s/apple/orange/gc高级功能
搜索功能
# 向下搜索
/pattern # 输入要搜索的模式,按 Enter 开始搜索
n # 查找下一个匹配项
N # 查找上一个匹配项
# 向上搜索
?pattern # 输入要搜索的模式,按 Enter 开始搜索
n # 查找上一个匹配项
N # 查找下一个匹配项
# 搜索选项
:set ignorecase # 忽略大小写
:set noignorecase # 区分大小写
:set hlsearch # 高亮显示搜索结果
:set nohlsearch # 关闭高亮显示
# 示例:向下搜索 "error"
/error
# 示例:向上搜索 "warning"
?warning
# 示例:关闭搜索高亮
:nohlsearch多窗口编辑
# 水平分割窗口
:split # 水平分割当前窗口
:split file # 水平分割并打开指定文件
# 垂直分割窗口
:vsplit # 垂直分割当前窗口
:vsplit file # 垂直分割并打开指定文件
# 窗口切换
Ctrl+w h # 切换到左侧窗口
Ctrl+w j # 切换到下方窗口
Ctrl+w k # 切换到上方窗口
Ctrl+w l # 切换到右侧窗口
Ctrl+w w # 循环切换窗口
# 调整窗口大小
Ctrl+w + # 增加当前窗口高度
Ctrl+w - # 减少当前窗口高度
Ctrl+w > # 增加当前窗口宽度
Ctrl+w < # 减少当前窗口宽度
Ctrl+w = # 平均分配窗口大小
# 关闭窗口
:close # 关闭当前窗口
:only # 关闭其他窗口,只保留当前窗口
# 示例:水平分割窗口并打开两个文件
vim file1.txt
:split file2.txt
# 示例:垂直分割窗口
:vsplit标签页管理
# 新建标签页
:tabnew # 新建一个空白标签页
:tabnew file # 新建标签页并打开指定文件
# 切换标签页
:tabnext # 切换到下一个标签页
:tabprev # 切换到上一个标签页
:tabfirst # 切换到第一个标签页
:tablast # 切换到最后一个标签页
# 关闭标签页
:tabclose # 关闭当前标签页
# 标签页命令快捷方式
gt # 切换到下一个标签页
gT # 切换到上一个标签页
Ngt # 切换到第 N 个标签页
# 示例:新建标签页并打开文件
:tabnew config.txt
# 示例:切换到第二个标签页
2gt宏录制
# 开始录制宏
q{register} # 例如 qq 开始录制到寄存器 q
# 执行要录制的操作
# ... 执行编辑操作 ...
# 停止录制
q # 按 q 停止录制
# 播放宏
@{register} # 例如 @q 播放寄存器 q 中的宏
n@{register} # 播放宏 n 次
# 示例:录制一个删除行尾空格的宏
qq # 开始录制到寄存器 q
:$ # 移动到行尾
:s/\s*$// # 删除行尾空格
j # 移动到下一行
q # 停止录制
# 示例:播放宏 10 次
10@q配置文件
全局配置文件
- 位置:
/etc/vim/vimrc或/etc/vimrc - 作用:对所有用户生效
用户配置文件
- 位置:
~/.vimrc - 作用:只对当前用户生效
常用配置选项
" 基本设置
set number " 显示行号
set relativenumber " 显示相对行号
set tabstop=4 " Tab 键宽度
set shiftwidth=4 " 缩进宽度
set expandtab " 将 Tab 转换为空格
set autoindent " 自动缩进
set smartindent " 智能缩进
set wrap " 自动换行
set linebreak " 单词边界换行
set ignorecase " 搜索时忽略大小写
set smartcase " 大写字母时区分大小写
set hlsearch " 高亮搜索结果
set incsearch " 增量搜索
set scrolloff=5 " 光标周围保留 5 行
set mouse=a " 启用鼠标支持
set encoding=utf-8 " 设置编码
set fileencoding=utf-8 " 设置文件编码
set cursorline " 高亮当前行
set cursorcolumn " 高亮当前列
set showmatch " 显示匹配的括号
set wildmenu " 命令行自动补全
set laststatus=2 " 显示状态栏
" 快捷键映射
map <F2> :w<CR> " F2 保存
map <F3> :q<CR> " F3 退出
map <F4> :wq<CR> " F4 保存并退出
" 插件管理
" 使用 Vundle 插件管理器的示例
" set nocompatible " 去除 VI 一致性
" filetype off " 关闭文件类型检测
" set rtp+=~/.vim/bundle/Vundle.vim
" call vundle#begin()
" Plugin 'VundleVim/Vundle.vim'
" Plugin 'scrooloose/nerdtree'
" Plugin 'tpope/vim-fugitive'
" Plugin 'vim-airline/vim-airline'
" call vundle#end()
" filetype plugin indent on " 开启文件类型检测插件系统
插件管理器
- Vundle:Vim Bundle,基于 Git 的插件管理器
- Pathogen:简单的插件管理解决方案
- vim-plug:轻量级插件管理器,支持并行安装
- Dein:高性能插件管理器
常用插件
- NERDTree:文件系统浏览器
- vim-airline:美化状态栏
- vim-fugitive:Git 集成
- syntastic:语法检查
- YouCompleteMe:代码补全
- emmet-vim:HTML/CSS 快速编辑
- vim-surround:处理引号、括号等包围符
- tabular:文本对齐
- ctrlp.vim:快速文件查找
- indentLine:显示缩进线
安装插件示例(使用 vim-plug)
# 安装 vim-plug
curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
# 在 ~/.vimrc 中配置插件
" vim-plug 配置
call plug#begin('~/.vim/plugged')
" 插件列表
Plug 'scrooloose/nerdtree' " 文件系统浏览器
Plug 'vim-airline/vim-airline' " 美化状态栏
Plug 'tpope/vim-fugitive' " Git 集成
Plug 'vim-syntastic/syntastic' " 语法检查
Plug 'junegunn/fzf', { 'do': { -> fzf#install() } } " 模糊查找
Plug 'junegunn/fzf.vim' " fzf 的 Vim 集成
call plug#end()
" 插件配置
" NERDTree 配置
map <F5> :NERDTreeToggle<CR>
let g:NERDTreeShowHidden=1
" airline 配置
let g:airline_theme='solarized'
let g:airline_powerline_fonts=1
# 安装插件
# 启动 vim 后执行
:PlugInstall
# 更新插件
:PlugUpdate
# 删除插件
# 在 ~/.vimrc 中注释或删除插件行,然后执行
:PlugClean实用技巧
快速保存与退出
# 保存文件
:w
# 保存并退出
:wq
ZZ # 命令模式下按 ZZ
# 退出不保存
:q!
ZQ # 命令模式下按 ZQ
# 保存为新文件
:w newfile.txt
# 保存并执行命令
:w | !command
# 示例:保存文件并编译
:w | !gcc -o program program.c
# 示例:强制退出不保存
:q!文本格式化
# 格式化整个文件
gg=G
# 格式化选中的文本
# 进入可视模式选择文本,然后按 =
# 调整缩进
>> # 增加缩进
<< # 减少缩进
# 对齐文本
:Tab /= # 以 = 为分隔符对齐
:Tab /, # 以 , 为分隔符对齐
# 示例:格式化整个文件
gg=G
# 示例:增加当前行缩进
>>批量操作
# 批量替换
:%s/old/new/g
# 批量删除空行
:g/^\s*$/d
# 批量删除注释行
:g/^\s*#/d
# 批量添加行号
:%!nl
# 排序文本
:sort # 按字母顺序排序
:sort -n # 按数字顺序排序
# 示例:删除所有空行
:g/^\s*$/d
# 示例:排序文本
:sort执行外部命令
# 执行外部命令并查看结果
:!command
# 执行外部命令并将结果插入到当前位置
:r !command
# 过滤并替换选中的文本
# 进入可视模式选择文本,然后按 ! 执行命令
# 示例:查看当前目录文件
:!ls -la
# 示例:将日期插入到当前位置
:r !date
# 示例:使用 sort 命令排序选中的文本
# 进入可视模式选择文本,按 !,输入 sort,按 Enter实操案例
案例1:编辑配置文件
目标:使用 vim 编辑 Apache 配置文件
步骤:
打开配置文件:
sudo vim /etc/apache2/apache2.conf查看文件内容:
# 移动到文件开头 gg # 向下滚动查看 Ctrl+f # 向下翻页修改配置:
# 搜索关键词 /DirectoryIndex # 进入插入模式修改 i # 修改内容 Esc # 返回命令模式保存并退出:
:wq
案例2:编写 Shell 脚本
目标:使用 vim 编写一个简单的 Shell 脚本
步骤:
创建并打开脚本文件:
vim backup.sh输入脚本内容:
# 进入插入模式 i # 输入脚本内容 #!/bin/bash # 备份目录 BACKUP_DIR="/backup" # 源目录 SOURCE_DIR="/home/user/data" # 创建备份目录 mkdir -p $BACKUP_DIR # 执行备份 echo "Starting backup..." tar -czf $BACKUP_DIR/backup_$(date +%Y%m%d).tar.gz $SOURCE_DIR echo "Backup completed!" # 返回命令模式 Esc保存并设置执行权限:
# 保存文件 :wq # 设置执行权限 chmod +x backup.sh
案例3:使用多窗口编辑
目标:使用 vim 的多窗口功能同时编辑多个文件
步骤:
打开第一个文件:
vim file1.txt水平分割窗口并打开第二个文件:
:split file2.txt垂直分割窗口并打开第三个文件:
Ctrl+w l # 切换到右侧窗口 :vsplit file3.txt在不同窗口间编辑:
# 切换窗口 Ctrl+w h # 左侧窗口 Ctrl+w j # 下方窗口 Ctrl+w k # 上方窗口 Ctrl+w l # 右侧窗口 # 在每个窗口中编辑内容保存所有文件并退出:
:wqall
案例4:使用宏录制批量处理文本
目标:使用 vim 的宏录制功能批量处理文本
步骤:
打开包含多个 IP 地址的文件:
vim ips.txt文件内容示例:
192.168.1.1 192.168.1.2 192.168.1.3 192.168.1.4 192.168.1.5录制宏:
# 移动到第一行 gg # 开始录制宏到寄存器 q qq # 执行操作:在行首添加 "IP: " IIP: <Esc> # 移动到下一行 j # 停止录制 q播放宏:
# 播放宏 4 次(处理剩余 4 行) 4@q查看结果:
IP: 192.168.1.1 IP: 192.168.1.2 IP: 192.168.1.3 IP: 192.168.1.4 IP: 192.168.1.5
常见问题与解决方案
问题1:vim 显示乱码
解决方案:
检查文件编码:
:set fileencoding设置正确的编码:
:set encoding=utf-8 :set fileencoding=utf-8在配置文件中添加编码设置:
# 在 ~/.vimrc 中添加 set encoding=utf-8 set fileencoding=utf-8 set fileencodings=utf-8,gbk,gb2312,gb18030
问题2:vim 无法使用鼠标
解决方案:
启用鼠标支持:
:set mouse=a在配置文件中添加:
# 在 ~/.vimrc 中添加 set mouse=a检查终端支持:确保使用的终端支持鼠标功能
问题3:vim 启动速度慢
解决方案:
检查插件:过多的插件会减慢启动速度,可禁用不必要的插件
优化配置:移除配置文件中不必要的设置
使用轻量级配置:对于临时编辑,可使用
vim -u NONE启动无配置的 vim检查网络连接:某些插件可能会尝试联网,导致启动延迟
问题4:无法退出 vim
解决方案:
检查模式:确保处于命令模式(按 Esc 键)
强制退出:
:q!保存并退出:
:wq使用 ZZ:在命令模式下按 ZZ 保存并退出
问题5:vim 搜索不区分大小写
解决方案:
设置区分大小写:
:set noignorecase在搜索时指定大小写:
- 使用
/pattern\C强制区分大小写 - 使用
/pattern\c强制忽略大小写
- 使用
在配置文件中设置:
# 在 ~/.vimrc 中添加 set noignorecase set smartcase " 当搜索模式包含大写字母时区分大小写
问题6:vim 缩进设置不正确
解决方案:
检查缩进设置:
:set tabstop? :set shiftwidth? :set expandtab?调整缩进设置:
:set tabstop=4 :set shiftwidth=4 :set expandtab在配置文件中添加:
# 在 ~/.vimrc 中添加 set tabstop=4 set shiftwidth=4 set expandtab set autoindent set smartindent
总结与最佳实践
核心概念回顾
编辑器模式:
- 命令模式:执行编辑命令
- 插入模式:输入文本
- 可视模式:选择文本块
- 命令行模式:执行保存、退出等操作
常用命令:
- 光标移动:h、j、k、l、w、b、e、0、^、$
- 编辑操作:i、a、o、dd、yy、p、u、Ctrl+r
- 搜索替换:/、?、:s/old/new/g
- 文件操作::w、:q、:wq、:q!
高级功能:
- 多窗口编辑::split、:vsplit、Ctrl+w 系列命令
- 标签页管理::tabnew、gt、gT
- 宏录制:q{register}、@{register}
- 插件系统:Vundle、vim-plug 等插件管理器
最佳实践
配置文件:
- 创建个人配置文件
~/.vimrc,根据个人习惯定制 - 合理设置缩进、编码、搜索等选项
- 映射常用操作到快捷键,提高效率
- 创建个人配置文件
插件管理:
- 使用插件管理器(如 vim-plug)管理插件
- 只安装必要的插件,避免过多插件影响性能
- 定期更新插件,保持功能和安全性
学习方法:
- 从基本命令开始,逐步学习高级功能
- 多实践,通过实际编辑任务巩固知识
- 参考帮助文档:
:help命令或在线资源 - 使用 cheat sheet 快速查阅常用命令
效率技巧:
- 掌握键盘快捷键,减少鼠标操作
- 使用宏录制处理重复任务
- 利用多窗口和标签页同时处理多个文件
- 结合外部命令增强编辑能力
常见场景:
- 编辑配置文件:使用 sudo vim
- 编写脚本:设置正确的文件类型和缩进
- 处理日志文件:使用搜索和多窗口功能
- 代码编辑:安装语法高亮和代码补全插件
实用配置示例
" ~/.vimrc 配置示例
set nocompatible " 去除 VI 一致性
set number " 显示行号
set relativenumber " 显示相对行号
set tabstop=4 " Tab 键宽度
set shiftwidth=4 " 缩进宽度
set expandtab " 将 Tab 转换为空格
set autoindent " 自动缩进
set smartindent " 智能缩进
set wrap " 自动换行
set linebreak " 单词边界换行
set ignorecase " 搜索时忽略大小写
set smartcase " 大写字母时区分大小写
set hlsearch " 高亮搜索结果
set incsearch " 增量搜索
set scrolloff=5 " 光标周围保留 5 行
set mouse=a " 启用鼠标支持
set encoding=utf-8 " 设置编码
set fileencoding=utf-8 " 设置文件编码
set cursorline " 高亮当前行
set showmatch " 显示匹配的括号
set wildmenu " 命令行自动补全
set laststatus=2 " 显示状态栏
" 快捷键映射
map <F2> :w<CR> " F2 保存
map <F3> :q<CR> " F3 退出
map <F4> :wq<CR> " F4 保存并退出
map <F5> :NERDTreeToggle<CR> " F5 打开/关闭文件浏览器
" 插件管理(使用 vim-plug)
call plug#begin('~/.vim/plugged')
Plug 'junegunn/vim-plug' " 插件管理器
Plug 'scrooloose/nerdtree' " 文件系统浏览器
Plug 'vim-airline/vim-airline' " 美化状态栏
Plug 'tpope/vim-fugitive' " Git 集成
Plug 'vim-syntastic/syntastic' " 语法检查
Plug 'junegunn/fzf' " 模糊查找
Plug 'junegunn/fzf.vim' " fzf 的 Vim 集成
call plug#end()
" NERDTree 配置
let g:NERDTreeShowHidden=1
let g:NERDTreeMinimalUI=1
" airline 配置
let g:airline_theme='solarized'
let g:airline_powerline_fonts=1
" syntastic 配置
let g:syntastic_check_on_open=1
let g:syntastic_check_on_wq=1
" fzf 配置
let g:fzf_preview_window='right:50%'学习资源推荐
官方文档:
:help命令:vim 内置帮助- Vim 官方网站
在线教程:
书籍:
- 《Vim 实用技巧》(Drew Neil)
- 《学习 Vi 和 Vim 编辑器》(Arnold Robbins)
- 《Vim 脚本编程》(Steve Oualline)
练习工具:
- Vim Adventures:通过游戏学习 Vim
- Open Vim:交互式 Vim 教程
- Vim Genius:Vim 命令练习
社区资源:
通过本教程的学习,你应该已经掌握了 vi/vim 的基本使用方法和一些高级功能。vi/vim 是一个功能强大、高度可定制的文本编辑器,需要通过不断练习来熟练掌握。记住,学习 vi/vim 是一个渐进的过程,从基本命令开始,逐步学习更高级的功能,最终你会发现它是一个非常高效、可靠的编辑工具,能够大大提高你的工作效率。