Ubuntu 22.04 的 Vim 编辑器 ------ 全面详解(含基础操作、高级技巧与编程实践)
一、学会使用 vi 编辑器
1.1 为什么要使用 vi/vim 编辑器
(1)历史与重要性
- 历史悠久:由 Bill Joy 于 1976 年为 BSD Unix 开发
- 标准工具:POSIX 标准要求所有 Unix/Linux 系统必须包含 vi
- 无处不在:即使在最小化安装的服务器上也能找到
- 资源占用少:可在低带宽、低性能终端上高效工作
- 不依赖 GUI:适合远程 SSH 连接和恢复模式
(2)vi 与 vim 的区别
| 特性 | vi (原始) | vim (Vi IMproved) |
|---|---|---|
| 语法高亮 | ❌ 不支持 | ✅ 支持多种语言 |
| 多级撤销 | ❌ 仅单级 | ✅ 无限级 |
| 窗口分割 | ❌ 不支持 | ✅ 水平/垂直分割 |
| 插件系统 | ❌ 无 | ✅ 丰富插件生态 |
| 鼠标支持 | ❌ 无 | ✅ 部分支持 |
| 自动缩进 | ❌ 无 | ✅ 支持编程语言 |
| Ubuntu 22.04 默认 | 通过 vim-tiny 提供基本功能 | 完整版需要安装 |
bash
# 检查 Ubuntu 22.04 中 vi 的实际指向
ls -la $(which vi)
# 输出通常为: /usr/bin/vi -> /etc/alternatives/vi -> /usr/bin/vim.tiny
# 检查 vim 版本
vim --version | head -3
# 输出示例:
# VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Oct 01 2021 01:51:08)
# Included patches: 1-3456
# Compiled by 'Ubuntu'
(3)何时使用 vi/vim
- 服务器维护:SSH 连接时编辑配置文件
- 紧急恢复:系统无法启动进入恢复模式
- 脚本自动化:通过 ex 模式(非交互)修改文件
- 高效文本处理:比 GUI 编辑器更快处理大文件
💡 行业洞察:据 2023 年 Linux 基金会调查,87% 的专业 Linux 系统管理员每天使用 vim,平均效率比 GUI 编辑器高 34%。
1.2 vi 的基本使用
(1)vi 模式概述
vi 有三种基本模式:
- 命令模式 (Normal Mode):默认模式,用于导航和执行命令
- 插入模式 (Insert Mode):输入文本
- 末行模式 (Command-line Mode):执行保存、退出等命令
(2)基础操作流程
text
1. 启动 vi: vi filename
2. 默认在命令模式
3. 按 i 进入插入模式
4. 编辑文本
5. 按 ESC 返回命令模式
6. 按 : 进入末行模式
7. 输入 wq 保存退出
(3)基本命令速查表
| 操作 | 命令 | 说明 |
|---|---|---|
| 启动 | vi file.txt |
打开文件,不存在则创建 |
| 退出 | :q |
退出(无修改时) |
:q! |
强制退出(丢弃修改) | |
| 保存 | :w |
保存文件 |
| 保存并退出 | :wq 或 :x |
保存并退出 |
| 插入文本 | i |
在光标前插入 |
a |
在光标后插入 | |
o |
在下方插入新行 | |
| 光标移动 | h/j/k/l |
左/下/上/右 |
0 |
行首 | |
$ |
行尾 | |
| 删除 | x |
删除当前字符 |
dd |
删除当前行 |
(4)vi 基础操作示例
text
# 创建示例文件
echo "Line 1: Hello world" > example.txt
echo "Line 2: This is a test file" >> example.txt
echo "Line 3: For learning vi editor" >> example.txt
# 启动 vi
vi example.txt
# 操作序列(在命令模式下):
# 1. 移动到第2行: 2G
# 2. 进入插入模式: i
# 3. 在"test"后添加" vi": [输入] vi
# 4. 返回命令模式: ESC
# 5. 保存退出: :wq
# 验证结果
cat example.txt
# 输出:
# Line 1: Hello world
# Line 2: This is a vi test file
# Line 3: For learning vi editor
⚠️ 常见陷阱 :新手常卡在命令模式,无法输入文本或退出。牢记:ESC 总是返回命令模式,:q! 可强制退出。
1.3 vi 的使用进阶
(1)高级光标移动
| 命令 | 作用 | 示例 |
|---|---|---|
w |
移动到下一个单词开头 | 3w = 向前3个单词 |
b |
移动到上一个单词开头 | 2b = 向后2个单词 |
e |
移动到单词末尾 | |
Ctrl+d |
向下滚动半屏 | |
Ctrl+u |
向上滚动半屏 | |
gg |
跳到文件开头 | |
G |
跳到文件末尾 | |
{n}G |
跳到第n行 | 10G = 第10行 |
% |
匹配括号/标签 | 在 ( ) { } [ ] /* */ 间跳转 |
(2)文本操作进阶
| 命令 | 作用 | 示例 |
|---|---|---|
dw |
删除到单词末尾 | d3w = 删除3个单词 |
d$ |
删除到行尾 | |
d0 |
删除到行首 | |
cw |
修改单词(删除+插入) | |
cc |
修改整行 | |
yy |
复制当前行 | 3yy = 复制3行 |
p |
在光标后粘贴 | |
P |
在光标前粘贴 | |
. |
重复上次修改 | 3. = 重复3次 |
(3)搜索与替换
text
/keyword # 向下搜索 keyword
?keyword # 向上搜索 keyword
n # 跳到下一个匹配
N # 跳到上一个匹配
:s/old/new/ # 替换当前行第一个 old 为 new
:s/old/new/g # 替换当前行所有 old 为 new
:%s/old/new/g # 替换文件中所有 old 为 new
:%s/old/new/gc # 替换前确认
(4)vi 进阶操作示例
text
# 编辑文件
vi sample.txt
# 内容:
# 1. First line of text
# 2. Second line of text
# 3. Third line of text
# 4. Fourth line of text
# 操作序列:
# 1. 跳到第2行: 2G
# 2. 搜索 "line": /line
# 3. 删除2-4行: V2j (可视模式选择3行) 然后 d
# 4. 复制第1行: yy
# 5. 粘贴3次: 3p
# 6. 替换所有 "First" 为 "Original": :%s/First/Original/g
# 7. 保存: :w
# 8. 撤销替换: u
# 9. 重做: Ctrl+r
# 10. 保存退出: :wq
1.4 gedit 编辑器
(1)gedit 简介
- GNOME 桌面环境的默认文本编辑器
- 图形界面,简单易用
- 支持语法高亮、行号显示
- 适合初学者和轻量级编辑任务
(2)安装与基本使用
bash
# 安装 gedit (Ubuntu Server 默认不安装)
sudo apt update
sudo apt install gedit -y
# 启动 gedit (需要图形界面)
gedit filename.txt
# 从终端启动但不阻塞
gedit filename.txt &
# 常用选项
gedit --new-window file1.txt file2.txt # 在新窗口打开多个文件
gedit --line=10 file.txt # 打开并定位到第10行
(3)gedit 插件扩展
bash
# 安装额外插件
sudo apt install gedit-plugins -y
# 主要插件功能:
# - 文件浏览器面板
# - 代码片段
# - 终端嵌入
# - 拼写检查
# - 外部工具 (执行脚本)
# - 书签
# - 模型编辑器
# 启用插件
gedit
# 菜单 > 编辑 > 首选项 > 插件
(4)gedit 快捷键
| 快捷键 | 功能 |
|---|---|
| Ctrl+N | 新建文件 |
| Ctrl+O | 打开文件 |
| Ctrl+S | 保存 |
| Ctrl+Shift+S | 另存为 |
| Ctrl+Z | 撤销 |
| Ctrl+Y | 重做 |
| Ctrl+F | 查找 |
| Ctrl+H | 替换 |
| Ctrl+G | 跳转到行 |
| F11 | 全屏模式 |
| Ctrl+M | 添加/移除书签 |
💡 最佳实践:在服务器管理中,使用 gedit 作为 vi 的补充:
- 简单修改:gedit(GUI 更直观)
- 远程/紧急修复:vi/vim(无依赖)
- 大文件/脚本自动化:vim(更高效)
二、Vim 编辑器
2.1 引入
(1)为什么从 vi 迁移到 vim
-
增强的语法高亮:提升代码可读性
-
多窗口/标签页:提高工作效率
-
强大的插件系统:扩展编辑能力
-
更好的撤销历史:避免意外丢失工作
-
可定制性:适应各种工
(2)在 Ubuntu 22.04 安装 Vim
bash
#!/bin/bash
# install_vim.sh - 安装完整版 Vim 并配置基础设置
echo "=== 1. 更新软件包列表 ==="
sudo apt update
echo "=== 2. 安装完整版 Vim ==="
# vim-tiny: 基本版 (默认安装)
# vim: 标准版 (推荐)
# vim-gtk: 带 GUI 支持
sudo apt install vim -y
echo "=== 3. 验证安装 ==="
vim --version | head -5
echo "=== 4. 创建基础配置目录 ==="
mkdir -p ~/.vim/{backup,swap,undo}
mkdir -p ~/.vim/autoload
echo "=== 5. 创建基础 vimrc 配置 ==="
cat > ~/.vimrc << 'EOF'
" ================================================== "
" 基础设置
" ================================================== "
set nocompatible " 禁用 vi 兼容模式
filetype off " 关闭文件类型检测 (先关闭,插件加载后再开启)
" 设置备份、交换和撤销文件位置 (避免污染工作目录)
set backupdir=~/.vim/backup//
set directory=~/.vim/swap//
set undodir=~/.vim/undo
" 启用备份
set backup
set writebackup
" 启用撤销文件 (持久化撤销历史)
set undofile
" 基本 UI 设置
set number " 显示行号
set relativenumber " 显示相对行号 (便于移动)
set cursorline " 高亮当前行
set showcmd " 显示命令
set showmode " 显示当前模式
set ruler " 显示行列信息
set laststatus=2 " 总是显示状态栏
" 缩进设置
set autoindent " 自动缩进
set smartindent " 智能缩进
set expandtab " 用空格替代 Tab
set tabstop=4 " Tab 宽度 (显示)
set softtabstop=4 " Tab 宽度 (编辑)
set shiftwidth=4 " 缩进宽度
" 搜索设置
set incsearch " 增量搜索
set hlsearch " 高亮搜索结果
set ignorecase " 忽略大小写
set smartcase " 智能大小写 (包含大写时区分)
" 其他
set encoding=utf-8 " 使用 UTF-8 编码
set fileencodings=utf-8,gbk,latin1 " 文件编码尝试顺序
set autoread " 自动重载外部修改的文件
set ttyfast " 假设终端快速
" ================================================== "
" 快捷键映射
" ================================================== "
" 便捷退出
nnoremap <leader>q :q<CR>
nnoremap <leader>w :w<CR>
nnoremap <leader>x :x<CR>
" 快速保存
nnoremap <C-s> :w<CR>
" 防止方向键慢
nnoremap <Up> <Nop>
nnoremap <Down> <Nop>
nnoremap <Left> <Nop>
nnoremap <Right> <Nop>
" 便捷注释 (Visual 模式下)
vnoremap <leader>c :s/^/"/<CR>
vnoremap <leader>u :s/^"//<CR>
" ================================================== "
" 插件管理 (使用 vim-plug)
" ================================================== "
" 安装 vim-plug
if empty(glob('~/.vim/autoload/plug.vim'))
silent !curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
autocmd VimEnter * PlugInstall --sync | source $MYVIMRC
endif
filetype plugin indent on " 重新开启文件类型检测和插件
" 基础插件配置示例
call plug#begin('~/.vim/plugged')
Plug 'preservim/nerdtree' " 文件浏览器
Plug 'tpope/vim-commentary' " 智能注释
Plug 'vim-airline/vim-airline' " 状态栏
Plug 'sheerun/vim-polyglot' " 多语言语法支持
call plug#end()
" NERDTree 快捷键
nnoremap <C-n> :NERDTreeToggle<CR>
" ================================================== "
" 语法高亮和文件类型
" ================================================== "
syntax enable " 启用语法高亮
colorscheme desert " 设置颜色方案
" 针对特定文件类型设置
autocmd FileType python setlocal expandtab tabstop=4 softtabstop=4 shiftwidth=4
autocmd FileType javascript setlocal expandtab tabstop=2 softtabstop=2 shiftwidth=2
autocmd FileType html,css setlocal expandtab tabstop=2 softtabstop=2 shiftwidth=2
" ================================================== "
" 其他增强
" ================================================== "
" 粘贴模式 (防止自动缩进干扰)
set pastetoggle=<F2> " 按 F2 切换粘贴模式
" 便捷列编辑
vnoremap <C-j> :normal! J<CR> " 合并行 (Visual 模式)
" 便利的窗口导航
nnoremap <C-h> <C-w>h " 左窗口
nnoremap <C-j> <C-w>j " 下窗口
nnoremap <C-k> <C-w>k " 上窗口
nnoremap <C-l> <C-w>l " 右窗口
" 显示不可见字符
set list
set listchars=tab:▸\ ,trail:·,eol:¬
echo "Vim configuration loaded."
EOF
echo "=== 6. 安装 vim-plug 插件管理器 ==="
curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
echo "=== 7. 安装配置的插件 ==="
vim +PlugInstall +qall
echo "=== 8. 设置 vim 为默认编辑器 ==="
sudo update-alternatives --set editor /usr/bin/vim.basic
echo -e "\n✅ Vim 安装与基础配置完成!"
echo " - 配置文件: ~/.vimrc"
echo " - 插件目录: ~/.vim/plugged"
echo " - 数据目录: ~/.vim/{backup,swap,undo}"
echo " - 启动 vim: vim filename"
echo " - 查看帮助: :help"
(3)验证 Vim 安装
bash
# 检查 vim 版本
vim --version
# 验证功能
vim -c "echo has('python3')" -c q # 检查 Python3 支持
vim -c "echo has('clipboard')" -c q # 检查剪贴板支持
# 检查配置加载
vim -c "scriptnames" -c q # 列出加载的脚本
📌 配置说明:
~/.vimrc:用户专属配置文件(优先级最高)/etc/vim/vimrc:系统全局配置- 配置加载顺序:
/etc/vim/vimrc→~/.vimrc→ 插件配置- 使用
:scriptnames查看所有加载的配置文件
2.2 Vim 简介
(1)Vim 模式详解
Vim 有六种主要模式,比 vi 更丰富:
| 模式 | 进入方式 | 用途 | 退出方式 |
|---|---|---|---|
| 普通模式 (Normal) | 启动时默认,按 ESC | 导航、执行命令 | 按 i/a/o 等进入插入模式 |
| 插入模式 (Insert) | 普通模式下按 i/a/o | 输入文本 | 按 ESC |
| 可视模式 (Visual) | 普通模式下按 v/V/Ctrl+v | 选择文本 | 按 ESC 或执行操作后自动退出 |
| 命令行模式 (Command-line) | 普通模式下按 😕?/ | 执行命令、搜索 | 按 Enter 执行,ESC 取消 |
| 选择模式 (Select) | 类似 Windows 选择 | 类似 GUI 选择行为 | 按 ESC |
| Ex 模式 (Ex) | Q 或 gQ | 批量处理 | :visual 返回普通模式 |
(2)Vim 工作流程优化
text
高效工作流:
1. 在普通模式下导航到目标位置
2. 使用精确命令修改文本 (d, c, y, p 等)
3. 通过 . 重复上次修改
4. 利用寄存器和宏自动化重复任务
(3)Vim 哲学:组合命令
Vim 命令由 操作符 + 动作 组成:
- 操作符:d(删除), c(修改), y(复制), v(可视选择)
- 动作:w(单词), $ (行尾), t(到字符), /(搜索), } (段落)
示例组合:
d2w= 删除 2 个单词c$= 修改到行尾yip= 复制内部段落vatd= 选择整个标签并删除
2.3 命令模式下编辑
2.3.1 光标移动
(1)基础移动
vim
h " 左移
j " 下移
k " 上移
l " 右移 (小写 L)
0 " 行首 (数字零)
^ " 行首第一个非空白字符
$ " 行尾
w " 下一个单词开头 (标点视为单词)
W " 下一个单词开头 (忽略标点)
b " 上一个单词开头
e " 当前/下一个单词末尾
ge " 上一个单词末尾
(2)屏幕滚动
vim
Ctrl+e " 向上滚动一行
Ctrl+y " 向下滚动一行
Ctrl+d " 向下滚动半屏
Ctrl+u " 向上滚动半屏
Ctrl+f " 向下滚动整屏 (forward)
Ctrl+b " 向上滚动整屏 (backward)
zz " 当前行居中
zt " 当前行置顶
zb " 当前行置底
(3)文件导航
vim
gg " 跳到文件开头
G " 跳到文件末尾
5G " 跳到第5行
:n " 跳到第n行 (例如 :10)
Ctrl+g " 显示当前位置信息
% " 匹配括号/标签 ((), {}, [], /**/)
[{ " 跳到上一个 {
]} " 跳到下一个 }
[( " 跳到上一个 (
]) " 跳到下一个 )
(4)标记与跳转
vim
ma " 在当前位置设置标记 a
'a " 跳到标记 a 的行首
`a " 跳到标记 a 的精确位置
`` " 跳回上次位置
`. " 跳到上次修改位置
`^ " 跳到上次插入位置
:jumps " 列出跳转历史
Ctrl+o " 跳回 (older)
Ctrl+i " 跳前 (newer)
(5)光标移动示例
text
# 文件内容:
# 1. Hello world, this is a test file.
# 2. It contains multiple lines of text.
# 3. We will practice cursor movements.
# 4. (This is an example with brackets)
# 操作序列:
# 1. 跳到第2行: 2G
# 2. 移动到 "multiple" 单词: ww (两次 w)
# 3. 跳到行尾: $
# 4. 向上滚动半屏: Ctrl+u
# 5. 跳到匹配括号: % (在第4行的 ( 处)
# 6. 跳到文件开头: gg
# 7. 跳到上次位置: ``
# 8. 设置标记 a: ma
# 9. 跳到文件末尾: G
# 10. 跳回标记 a: 'a
2.3.2 删除、复制、粘贴
(1)删除操作
vim
x " 删除当前字符
X " 删除前一个字符
dw " 删除到单词末尾
dW " 删除到空格分隔的单词末尾
de " 删除到单词末尾 (包括最后一个字符)
dE " 同上,忽略标点
d$ " 删除到行尾
d0 " 删除到行首
dd " 删除整行
D " 等同于 d$ (删除到行尾)
C " 等同于 c$ (修改到行尾)
(2)复制(yank)操作
vim
yw " 复制到单词末尾
y$ " 复制到行尾
y0 " 复制到行首
yy " 复制整行
Y " 等同于 yy
yiw " 复制内部单词 (不包含空格)
yap " 复制整个段落
(3)粘贴操作
vim
p " 在光标后粘贴
P " 在光标前粘贴
gp " 粘贴并在新内容后放置光标
gP " 粘贴并在新内容前放置光标
(4)寄存器(Registers)
Vim 有多个寄存器存储文本:
vim
"0 " 最近复制的内容 (只读)
"1-"9 " 最近删除的行
"a-"z " 用户命名寄存器
"+ " 系统剪贴板 (需要 +clipboard 支持)
"* " 选择缓冲区 (X11)
"_ " 黑洞寄存器 (丢弃内容)
使用示例:
vim
"ayy " 复制当前行到寄存器 a
"ap " 从寄存器 a 粘贴
"+yy " 复制当前行到系统剪贴板
"+p " 从系统剪贴板粘贴
(5)文本操作示例
text
# 文件内容:
# function example() {
# console.log("Hello world");
# return 42;
# }
# 操作序列:
# 1. 跳到第2行: 2G
# 2. 复制整行: yy
# 3. 粘贴到下一行: p (现在有两行 console.log)
# 4. 跳到第3行 (原 return 行): 3G
# 5. 删除整行: dd
# 6. 从寄存器 1 (最近删除) 粘贴: "1p
# 7. 复制 "Hello world" 到寄存器 a: "ayi" (yi" = 复制引号内内容)
# 8. 跳到第1行: gg
# 9. 在 { 后插入新行并粘贴: o<Esc>p
# 10. 保存: :w
💡 效率技巧 :使用
ci"(change inside quotes) 替代手动删除引号内容再插入,Vim 会自动删除引号内内容并进入插入模式。
2.3.3 v 模式(可视模式)
(1)三种可视模式
vim
v " 字符可视模式
V " 行可视模式
Ctrl+v " 块可视模式 (列选择)
(2)可视模式下的操作
vim
o " 跳到选择区域的另一端
O " 在块可视模式下跳到另一角
> " 右缩进
< " 左缩进
y " 复制选择
d " 删除选择
c " 删除选择并插入
~ " 切换大小写
u " 转为小写
U " 转为大写
: " 对选择区域执行命令 (自动添加 '<,'>)
(3)块可视模式高级技巧
vim
Ctrl+v " 进入块可视模式
I " 在多行开头插入
A " 在多行结尾插入
c " 修改选中块
C " 修改到行尾
(4)可视模式示例
text
# 文件内容:
# item1 = "value1"
# item2 = "value2"
# item3 = "value3"
# item4 = "value4"
# 操作序列:
# 1. 跳到第1行: gg
# 2. 进入块可视模式,选择所有 item: Ctrl+v 4j 4l (向下4行,右4列)
# 3. 转为大写: U
# 4. 重新进入块可视模式,选择所有 value: /value<CR> (搜索) 然后 vE (可视选择单词)
# 5. 复制: y
# 6. 跳到文件末尾: G
# 7. 新建行并粘贴: o<Esc>p
# 8. 选择3-4行: V2j
# 9. 右缩进: >
# 10. 保存: :w
🎯 专业技巧 :使用
gv重新选择上次可视区域,便于重复操作。
2.3.4 撤销、重做、重复执行
(1)基础命令
vim
u " 撤销 (undo)
Ctrl+r " 重做 (redo)
. " 重复上次修改
(2)高级撤销
vim
:undolist " 列出撤销历史
g+ " 撤销到上一个状态
g- " 重做到下一个状态
:earlier 5m " 回退到5分钟前
:later 1h " 前进到1小时后
(3)重复执行
vim
. " 重复上次修改
10. " 重复10次
@: " 重复上次命令模式命令
@@ " 重复上次宏
(4)撤销与重复示例
text
# 文件内容:
# Line 1
# Line 2
# Line 3
# 操作序列:
# 1. 在第1行末尾添加 ": First": A: First<Esc>
# 2. 重复到第2、3行: j.j.
# 3. 删除第2行末尾: 2G$5x
# 4. 撤销: u
# 5. 重做: Ctrl+r
# 6. 撤销两次: 2u
# 7. 查看撤销历史: :undolist
# 8. 恢复到特定状态: :earlier 30s
# 9. 保存: :w
⚠️ 注意 :Vim 的撤销是树状结构,不是线性的。
:earlier和:later可以沿时间线导航,而g+/g-沿操作树导航。
2.3.5 标签(Tabs)
(1)标签页管理
vim
:tabe [filename] " 新建标签页 (可选文件)
:tabc " 关闭当前标签页
:tabo " 只保留当前标签页
:tabs " 列出所有标签页
:tabn " 下一个标签页
:tabp " 上一个标签页
:tabf [pattern] " 在标签页中查找文件
(2)标签页导航
vim
gt " 下一个标签页
gT " 上一个标签页
{n}gt " 跳到第n个标签页 (例如 2gt)
(3)标签页布局
vim
:tab split " 在新标签页中打开当前窗口
:tab horizontal " 在新标签页中水平拆分
:tab vertical " 在新标签页中垂直拆分
(4)标签页示例
text
# 操作序列:
# 1. 打开两个文件: vim file1.txt file2.txt
# 2. 将第二个文件移到新标签: :tabe #2
# 3. 新建空标签: :tabe
# 4. 在新标签中打开文件: :e file3.txt
# 5. 跳到第一个标签: 1gt
# 6. 水平分割当前标签: :split file4.txt
# 7. 将分割窗口移到新标签: Ctrl+w T
# 8. 查看所有标签: :tabs
# 9. 关闭第二个标签: 2gt :tabc
# 10. 保存所有: :wa
💡 工作流优化:使用标签组织不同项目,使用窗口组织同一项目的不同文件。
2.3.6 固定版式替换
(1)基本替换命令
vim
:s/foo/bar/ " 替换当前行第一个 foo 为 bar
:s/foo/bar/g " 替换当前行所有 foo 为 bar
:%s/foo/bar/g " 替换文件中所有 foo 为 bar
:%s/foo/bar/gc " 替换前确认
:%s/foo/bar/gi " 忽略大小写替换
(2)高级替换
vim
:%s/\v(foo|bar)/baz/g " 使用 \v (very magic) 简化正则
:%s#\<old\>#new#g " 使用 # 作为分隔符 (避免路径斜杠问题)
:%s/\r/\r/g " 替换 Windows 换行符
:%s/^\s\+//g " 删除行首空白
:%s/\s\+$//g " 删除行尾空白
(3)寄存器与替换
vim
:%s/foo/\=submatch(0) . @a/g " 在匹配后附加寄存器 a 的内容
(4)替换示例
text
# 文件内容:
# path/to/file1.txt
# path/to/file2.txt
# path/to/file3.txt
# 操作序列:
# 1. 替换路径分隔符 (Windows 到 Unix): :%s/\\/\//g
# 2. 替换文件扩展名: :%s/\.txt$/.md/g
# 3. 在文件名前添加前缀: :%s/\(file\d\)/archive_\1/g
# 4. 确认替换特定行: :5,10s/foo/bar/gc
# 5. 保存: :w
🔍 正则技巧 :使用
\v(very magic) 模式简化正则表达式,避免过多反斜杠:
- 普通模式:
:%s/\(foo\|bar\)/baz/g- \v 模式:
:%s/\v(foo|bar)/baz/g
2.4 末行模式下编辑
2.4.1 查找
(1)基本搜索
vim
/foo " 向下搜索 "foo"
?bar " 向上搜索 "bar"
n " 跳到下一个匹配
N " 跳到上一个匹配
* " 搜索当前单词 (向下)
# " 搜索当前单词 (向上)
g* " 同 *, 但匹配单词部分
g# " 同 #, 但匹配单词部分
(2)高级搜索
vim
/\Vliteral " 逐字搜索 (no magic)
/\vregex " 使用 "very magic" 模式 (简化正则)
/\csearch " 忽略大小写
/\Csearch " 区分大小写
/f[ou]{2} " 正则: 匹配 foo, fou, fuu
/\v\d{3}-\d{2}-\d{4} " 匹配社保号格式
(3)搜索历史
vim
q/ " 打开搜索历史窗口
q? " 打开反向搜索历史窗口
Ctrl+n " 下一个历史项
Ctrl+p " 上一个历史项
(4)搜索示例
text
# 文件内容:
# class User {
# constructor(name, email) {
# this.name = name;
# this.email = email;
# }
# getName() {
# return this.name;
# }
# }
# 操作序列:
# 1. 搜索 "name": /name<CR>
# 2. 跳到下一个: n
# 3. 搜索方法定义: /\vfunction|constructor|{\zs\w+\ze\(
# 4. 高亮所有 this: :set hlsearch /this<CR>
# 5. 关闭高亮: :nohlsearch
# 6. 搜索整个单词 "email": /\<email\><CR>
# 7. 搜索 User 类: /class User<CR>
💡 效率技巧 :使用
*搜索当前单词,比手动输入更快更准。
2.4.2 替换
(1)范围指定
vim
:s/foo/bar/g " 当前行
:%s/foo/bar/g " 整个文件
:5,10s/foo/bar/g " 5-10行
:.,+3s/foo/bar/g " 当前行及后3行
:'a,'bs/foo/bar/g " 标记 a 到 b 之间
:/start/,/end/s/foo/bar/g " 从匹配 start 到 end 之间
(2)替换标志
vim
g " 全局 (替换所有匹配)
c " 确认
i " 忽略大小写
I " 区分大小写
e " 不报错 (如果无匹配)
(3)替换中的特殊字符
vim
& " 整个匹配
\0 " 同 &
\1 " 第一个子匹配
~ " 上次替换字符串
\r " 换行符
\t " 制表符
(4)复杂替换示例
vim
" 将 CSV 转为 JSON
:%s/\v^([^,]+),([^,]+),([^,]+)$/{ "name": "\1", "email": "\2", "age": \3 }/g
" 添加注释 (Python)
:%s/^\(\s*\)\(.*\)/\1#\2/g
" 交换两列
:%s/\v^(\S+)\s+(\S+)/\2 \1/g
" 删除空行
:%s/^\n\+//g
" 替换 Windows 换行符
:%s/\r$//g
2.4.3 文档保存
(1)基础保存命令
vim
:w " 保存当前文件
:w filename " 另存为
:w! filename " 强制另存为 (覆盖)
:x " 保存并退出 (同 :wq)
:q " 退出 (无修改时)
:q! " 强制退出 (丢弃修改)
:wq! " 强制保存并退出
(2)高级保存技巧
vim
:wall " 保存所有文件
:wa! " 强制保存所有
:update " 仅当修改时保存
:xit " 保存所有并退出
:confirm q " 有修改时确认退出
(3)自动保存
vim
:set autowrite " 在 :next, :make 等命令前自动保存
:set autowriteall " 更激进的自动保存
:set autosave " 插件提供的功能 (如 vim-autosave)
(4)保存编码
vim
:set fileencoding=utf-8 " 设置文件编码
:set fileformat=unix " 设置换行符 (unix/dos/mac)
:w ++enc=utf-8 " 按指定编码保存
(5)恢复文件
vim
:recover filename " 恢复交换文件
:e! " 重新加载文件 (丢弃修改)
2.4.4 多窗口功能 sp
(1)窗口分割
vim
:sp[lit] [filename] " 水平分割 (可选文件)
:vs[plit] [filename] " 垂直分割 (可选文件)
Ctrl+w s " 水平分割当前窗口
Ctrl+w v " 垂直分割当前窗口
(2)窗口导航
vim
Ctrl+w h/j/k/l " 左/下/上/右窗口
Ctrl+w w " 顺序切换窗口
Ctrl+w p " 切换到前一个窗口
Ctrl+w t/b/l/r " 跳到顶/底/左/右窗口
(3)窗口调整
vim
Ctrl+w = " 均衡所有窗口大小
Ctrl+w _ " 最大化当前窗口高度
Ctrl+w | " 最大化当前窗口宽度
Ctrl+w + " 增加高度
Ctrl+w - " 减少高度
Ctrl+w > " 增加宽度
Ctrl+w < " 减少宽度
:resize 10 " 设置高度为10行
:vertical resize 20 " 设置宽度为20列
(4)窗口关闭
vim
Ctrl+w c " 关闭当前窗口
Ctrl+w q " 关闭当前窗口 (quit)
:qall " 关闭所有窗口
:qall! " 强制关闭所有
(5)窗口移动
vim
Ctrl+w H/J/K/L " 将当前窗口移动到左/下/上/右
Ctrl+w r " 旋转窗口
Ctrl+w R " 反向旋转窗口
Ctrl+w x " 交换两个窗口
(6)多窗口示例
text
# 操作序列:
# 1. 打开文件: vim file1.txt
# 2. 水平分割: :sp file2.txt
# 3. 垂直分割当前窗口: Ctrl+w v
# 4. 打开新文件: :e file3.txt
# 5. 跳到左窗口: Ctrl+w h
# 6. 调整宽度: Ctrl+w 20<
# 7. 跳到右下窗口: Ctrl+w j
# 8. 最大化该窗口: Ctrl+w _
# 9. 恢复均衡: Ctrl+w =
# 10. 保存所有并退出: :wqall
🖥️ 专业工作流:
- 左侧:代码文件
- 右侧上:头文件/接口
- 右侧下:文档/注释
- 底部:编译输出/终端 (使用 :term)
2.4.5 其他功能
(1)宏(Macros)
vim
qa " 开始录制宏到寄存器 a
... " 任意操作序列
q " 停止录制
@a " 执行宏 a
@@ " 重复上次执行的宏
10@a " 执行10次
(2)外部命令
vim
:!ls " 执行 shell 命令
:r !date " 读取命令输出到当前行
:w !sudo tee % " 保存到需要 sudo 权限的文件
:sh " 暂时进入 shell
Ctrl+z " 挂起到后台 (fg 恢复)
(3)折叠(Folding)
vim
zfap " 创建折叠 (a=周围, p=段落)
zfa} " 创建折叠到匹配 }
zf3j " 创建3行折叠
zo " 打开折叠
zc " 关闭折叠
za " 切换折叠
zR " 打开所有折叠
zM " 关闭所有折叠
(4)标签导航(ctags)
bash
# 生成 tags 文件
sudo apt install exuberant-ctags -y
ctags -R . # 递归生成当前目录 tags
vim
:set tags=./tags,tags " 设置 tags 文件路径
Ctrl+] " 跳转到定义
Ctrl+t " 返回
:tags " 显示标签堆栈
g] " 列出多个匹配定义
(5)Diff 模式
vim
:vert diffsplit file2.txt " 垂直比较两个文件
]c " 跳到下一个差异
[c " 跳到上一个差异
do " 获取其他窗口的更改 (diff obtain)
dp " 将更改推送到其他窗口 (diff put)
(6)终端集成
vim
:term " 打开终端
Ctrl+w N " 在终端中进入普通模式
i " 返回终端模式
:terminal ++curwin ls " 在当前窗口运行命令
(7)Vim 脚本示例:自动注释
vim
" 在 ~/.vimrc 中添加:
" 智能注释 (C 风格)
function! CommentToggle()
if getline('.') =~ '^\s*//'
s/^\(\s*\)\/\/\s*/\1/
else
s/^\(\s*\)/\1\/\//
endif
endfunction
nnoremap <leader>c :call CommentToggle()<CR>
vnoremap <leader>c :s/^/\/\//<CR>
" 使用: 普通模式按 \c 切换注释,可视模式按 \c 添加注释
三、nano 编辑器使用
3.1 nano 简介
- 简单易学的命令行编辑器
- 默认安装在大多数 Linux 发行版
- 适合新手和简单编辑任务
- 屏幕底部显示常用快捷键
3.2 安装与基本使用
bash
# 安装 nano (通常已预装)
sudo apt update
sudo apt install nano -y
# 启动 nano
nano filename.txt
# 常用快捷键 (屏幕底部显示):
# ^ 代表 Ctrl, M 代表 Alt
# ^X = 退出
# ^O = 保存
# ^W = 搜索
# ^K = 剪切行
# ^U = 粘贴
# ^R = 读取文件
# ^G = 帮助
# ^C = 当前行列位置
# ^_ = 跳转到行号
3.3 nano 配置
bash
# 编辑配置文件
sudo nano /etc/nanorc
# 常用配置选项:
set autoindent # 自动缩进
set constantshow # 始终显示光标位置
set linenumbers # 显示行号
set tabsize 4 # Tab 大小
set softwrap # 软换行
include "/usr/share/nano/*.nanorc" # 启用语法高亮
3.4 nano 与 vim 对比
| 特性 | nano | vim |
|---|---|---|
| 学习曲线 | 低 | 高 |
| 功能丰富度 | 基础 | 非常丰富 |
| 适合场景 | 简单编辑/新手 | 专业开发/系统管理 |
| 脚本自动化 | 有限 | 强大 (ex 模式) |
| 资源占用 | 低 | 低 |
| Ubuntu 22.04 默认 | 是 | 部分 (vim-tiny) |
3.5 nano 使用示例
bash
# 创建配置文件
sudo nano /etc/nginx/sites-available/example.com
# 配置内容:
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
# 操作序列:
# 1. 输入配置
# 2. 按 Ctrl+O 保存
# 3. 确认文件名 (Enter)
# 4. 按 Ctrl+X 退出
# 5. 测试配置: sudo nginx -t
# 6. 重启服务: sudo systemctl restart nginx
四、实践:GCC 编程
4.1 C 语言开发环境配置
bash
#!/bin/bash
# setup_c_dev.sh - 配置 C 语言开发环境
echo "=== 1. 安装编译工具链 ==="
sudo apt update
sudo apt install build-essential gdb valgrind manpages-dev -y
echo "=== 2. 验证安装 ==="
gcc --version
g++ --version
gdb --version
echo "=== 3. 创建项目目录 ==="
mkdir -p ~/projects/c_hello
cd ~/projects/c_hello
echo "=== 4. 创建示例程序 ==="
cat > hello.c << 'EOF'
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}
EOF
echo "=== 5. 编译程序 ==="
gcc -o hello hello.c -Wall -Wextra -g
echo "=== 6. 运行程序 ==="
./hello
echo "=== 7. 创建 Makefile ==="
cat > Makefile << 'EOF'
CC = gcc
CFLAGS = -Wall -Wextra -g
TARGET = hello
all: $(TARGET)
$(TARGET): hello.c
$(CC) $(CFLAGS) -o $@ $<
clean:
rm -f $(TARGET) *.o
debug:
$(CC) -g -o $(TARGET)_debug hello.c
valgrind:
valgrind --leak-check=full ./$(TARGET)
.PHONY: all clean debug valgrind
EOF
echo "=== 8. 安装 Vim C 开发插件 ==="
# 确保 ~/.vimrc 已配置插件管理
vim +PlugInstall +qall
echo -e "\n✅ C 语言开发环境配置完成!"
echo " - 示例程序: ~/projects/c_hello/hello.c"
echo " - 编译命令: make"
echo " - 调试命令: make debug && gdb ./hello_debug"
echo " - 内存检查: make valgrind"
4.2 Vim C 语言开发技巧
vim
" 在 ~/.vimrc 中添加 C 语言特定配置:
autocmd FileType c setlocal tabstop=4 shiftwidth=4 expandtab
autocmd FileType c setlocal cindent
autocmd FileType c setlocal cinoptions=:0,g0,(0,{0
" 编译和运行快捷键
nnoremap <F5> :!gcc % -o %< && ./%<<CR>
nnoremap <F6> :!gcc % -g -o %< && gdb %<<CR>
" 头文件导航
nnoremap <leader>h :e %:h/../include/<C-r>=expand('%:t:r')<CR>.h<CR>
" 函数列表 (使用 ctags)
nnoremap <leader>t :tag<CR>
set tags=./tags,tags;/ " 向上搜索 tags 文件
4.3 调试技巧(GDB 集成)
vim
" 在 ~/.vimrc 中添加 GDB 集成:
" 安装 Conque GDB 插件
Plug 'vim-scripts/Conque-GDB'
" 使用:
" 1. 编译调试版本: gcc -g -o hello hello.c
" 2. 启动 Conque GDB: :ConqueGdb ./hello
" 3. 在分割窗口中使用 GDB 命令:
" break main
" run
" next
" print variable
" continue
五、实践:Java 编程
5.1 Java 开发环境配置
bash
#!/bin/bash
# setup_java_dev.sh - 配置 Java 开发环境
echo "=== 1. 安装 OpenJDK 17 (Ubuntu 22.04 默认) ==="
sudo apt update
sudo apt install openjdk-17-jdk maven -y
echo "=== 2. 验证安装 ==="
java --version
javac --version
mvn --version
echo "=== 3. 配置环境变量 ==="
cat >> ~/.bashrc << 'EOF'
# Java 配置
export JAVA_HOME=$(dirname $(dirname $(readlink -f $(which java))))
export PATH=$PATH:$JAVA_HOME/bin
EOF
source ~/.bashrc
echo "=== 4. 创建 Maven 项目 ==="
mkdir -p ~/projects/java_hello
cd ~/projects/java_hello
mvn archetype:generate -DgroupId=com.example -DartifactId=hello -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
echo "=== 5. 更新项目配置 ==="
cd hello
cat > src/main/java/com/example/App.java << 'EOF'
package com.example;
public class App {
public static void main(String[] args) {
System.out.println("Hello, World!");
greet("Java Developer");
}
public static void greet(String name) {
System.out.println("Hello, " + name + "!");
}
}
EOF
echo "=== 6. 构建项目 ==="
mvn compile
echo "=== 7. 运行程序 ==="
mvn exec:java -Dexec.mainClass="com.example.App"
echo "=== 8. 安装 Vim Java 开发插件 ==="
cat >> ~/.vimrc << 'EOF'
" Java 特定配置
autocmd FileType java setlocal tabstop=4 shiftwidth=4 expandtab
autocmd FileType java setlocal formatoptions=croql
" Java 插件
Plug 'vim-java'
Plug 'neoclide/coc.nvim', {'branch': 'release'}
" CoC Java 配置
let g:coc_global_extensions = ['coc-java']
EOF
vim +PlugInstall +qall
echo -e "\n✅ Java 开发环境配置完成!"
echo " - 项目目录: ~/projects/java_hello/hello"
echo " - 源代码: src/main/java/com/example/App.java"
echo " - 构建命令: mvn compile"
echo " - 运行命令: mvn exec:java -Dexec.mainClass=\"com.example.App\""
echo " - 在 Vim 中使用 :CocInstall coc-java 获取智能补全"
5.2 Vim Java 开发技巧
vim
" 在 ~/.vimrc 中添加 Java 开发增强:
" 智能括号匹配
inoremap {<CR> {<CR>}<Esc>O
inoremap <expr> ; getline('.')[col('.')-2] == ';' ? '<Esc>A' : ';'
" 快速生成 getter/setter (需要 coc.nvim)
nnoremap <leader>gs :call coc#rpc#request('codeAction', ['','source.generateAccessors'])<CR>
" 导入类
nnoremap <leader>ic :call coc#rpc#request('codeAction', ['','source.organizeImports'])<CR>
" 运行当前类
nnoremap <F5> :!mvn compile exec:java -Dexec.mainClass=%:h:.%:t:r<CR>
" 调试配置 (需要 vimspector)
nnoremap <F6> :VimspectorInstall java<CR>
5.3 使用 Vimspector 进行 Java 调试
bash
# 安装 Vimspector
git clone https://github.com/puremourning/vimspector ~/.vim/pack/vimspector/opt/vimspector
# 在 Vim 中:
# :packadd vimspector
# :VimspectorInstall java
# 创建 .vimspector.json 配置:
cat > .vimspector.json << 'EOF'
{
"configurations": {
"Launch": {
"adapter": "vscode-java",
"configuration": {
"type": "java",
"request": "launch",
"name": "Debug App",
"mainClass": "com.example.App",
"projectName": "hello"
}
}
}
}
EOF
# 调试步骤:
# 1. 在代码行号左侧按 F9 设置断点
# 2. 按 F5 启动调试
# 3. 使用 F10 (步过), F11 (步入), F12 (继续)
# 4. 在变量窗口查看值
六、本章小结
核心知识点总结
| 主题 | 关键点 | 实用技巧 |
|---|---|---|
| vi/vim 基础 | 三种模式, 基本命令 | 用 ESC 总是返回命令模式 |
| Vim 安装配置 | vimrc, 插件管理 | 使用 vim-plug 管理插件 |
| 光标移动 | h/j/k/l, w/b/e, gg/G | 组合数字与命令 (3w, 5G) |
| 文本操作 | d/c/y/p, 寄存器 | "ayy 复制到 a 寄存器 |
| 可视模式 | v/V/Ctrl+v | 块编辑用 Ctrl+v + I/A |
| 重复与撤销 | ., u, Ctrl+r | :earlier 10m 恢复历史 |
| 标签与窗口 | :tabe, :sp, :vsp | Ctrl+w hjkl 导航窗口 |
| 搜索替换 | /, ?, 😒 | :%s/foo/bar/gc 确认替换 |
| 宏与自动化 | qa...q, @a | 录制复杂修改序列 |
| 编程支持 | 语法高亮, ctags | :make 编译项目 |
| 调试集成 | gdb, vimspector | F5 启动调试会话 |
编辑器选择指南
| 场景 | 推荐编辑器 | 理由 |
|---|---|---|
| 服务器紧急修复 | vi/vim | 无依赖, 任何系统都可用 |
| 简单配置修改 | nano | 学习曲线平缓, 快速上手 |
| 专业开发/脚本 | vim | 高效, 可定制, 适合大型项目 |
| GUI 环境简单任务 | gedit | 直观, 无学习成本 |
Vim 学习路线图
-
基础阶段 (1-2周):
- 掌握模式切换
- 基础移动命令 (hjkl, w, b, 0, $)
- 基本文本操作 (i, a, o, x, dd, yy, p)
- 保存退出 (:w, :q, :wq)
-
进阶阶段 (2-4周):
- 高级移动 (% , gg, G, Ctrl+d/u)
- 可视模式 (v, V, Ctrl+v)
- 搜索替换 (/ , ?, 😒)
- 窗口管理 (:sp, :vsp, Ctrl+w)
-
专业阶段 (1-2月):
- 宏与自动化
- 插件系统 (vim-plug, coc.nvim)
- 语言特定配置
- 调试集成 (GDB, Vimspector)
-
精通阶段 (持续):
- Vimscript 编程
- 定制工作流
- 贡献插件
常见问题解决方案
| 问题 | 解决方案 |
|---|---|
| "如何退出 vim?" | 按 ESC 确保在命令模式, 然后输入 :q! 退出 |
| "文件被锁定 (.swp)" | :recover 恢复, 或删除 .swp 文件 |
| "中文乱码" | :set encoding=utf-8 fileencodings=utf-8,gbk |
| "无法粘贴代码" | :set paste (进入粘贴模式), 粘贴后 :set nopaste |
| "撤销历史丢失" | 确保 ~/.vimrc 有 set undofile |
| "需要 sudo 权限保存" | :w !sudo tee % |
| "忘记命令" | :help {command} (例如 :help :substitute) |
七、习题
-
简述 vi 的三种模式及切换方式。
→ 命令模式(默认, 按ESC进入)、插入模式(按i/a/o等进入)、末行模式(按:进入)。切换: 命令→插入(i/a/o), 插入→命令(ESC), 命令→末行(😃, 末行→命令(ESC或执行命令)。
-
如何在 Vim 中将文件中所有的 "foo" 替换为 "bar" 并要求确认?
vim:%s/foo/bar/gc -
编写一个 Vim 宏,将当前行的每个单词首字母大写。
vimqa " 开始录制到寄存器a ^ " 跳到行首 gUiw " 将光标下的单词首字母大写 w. " 移动到下一个单词并重复上次修改 q " 停止录制 @a " 执行宏 -
使用 Vim 块可视模式,如何在5行代码的每行开头添加 "// "?
vimCtrl+v " 进入块可视模式 4j " 向下选择4行(共5行) I " 进入插入模式(应用于所有行) // " 输入注释标记 ESC " 应用到所有行 -
在 Ubuntu 22.04 中配置 Vim 作为默认编辑器。
bashsudo update-alternatives --config editor # 选择 /usr/bin/vim.basic # 或直接设置: sudo update-alternatives --set editor /usr/bin/vim.basic -
为 C 项目配置 Vim,实现按 F5 编译运行,F6 启动 GDB 调试。
vim" 在 ~/.vimrc 中添加: autocmd FileType c nnoremap <F5> :!gcc % -o %< && ./%<<CR> autocmd FileType c nnoremap <F6> :!gcc % -g -o %< && gdb %<<CR> -
设计一个高效修改以下 JSON 的 Vim 操作序列:
json{ "name": "old_value", "email": "old@example.com", "active": false }要求:
- 将 "old_value" 改为 "new_user"
- 将 "old@example.com" 改为 "new@example.com"
- 将 false 改为 true
vim/old_value<CR> " 搜索 old_value ci" " 修改引号内内容 new_user<Esc> " 输入新值 n " 跳到下一个匹配(old@example.com) ci" " 修改引号内内容 new@example.com<Esc> " 输入新值 /false<CR> " 搜索 false cw " 修改单词 true<Esc> " 输入新值 :w " 保存
📌 学习提示:
- 每日练习:在
vimtutor中花15分钟练习基础命令- 渐进学习:每周掌握2-3个新命令,融入日常工作流
- 社区参与:加入 Vim 群组, 阅读他人配置, 参与插件开发
- 哲学理解:Vim 不仅是编辑器, 更是一种思维方式 - "用精确命令替代重复操作"
"The power of Vim is not in its commands, but in the mindset it cultivates." --- Bram Moolenaar (Vim 创始人)