Linux常用命令-vim

命令

vim

描述

Vi IMproved, a programmers text editor
文本编辑器

用法

1
2
vim [options] [file ..]
vim [options] dir

选项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Options:
-d 并列打开多个文件进行差异对比,切换窗口先按ctrl+w,然后按ctrl+h或ctrl+l,退出所有窗口命令:qa
-m 只读模式打开文件
-b 二进制模式打开文件
-n 不使用swap临时文件,直接加载到内存编辑
-r,-L 列出所有的swap临时文件并退出,用于恢复崩溃的会话
-r FILENAME 恢复崩溃的会话文件
-u <vimrc> 指定vimrc配置文件
-i <viminfo> 指定viminfo文件
-p[N] 打开多个标签页,注意参数之间没有空格,如打开3个标签页-p3,切换命令gt
-o[N] 打开多个窗口水平排列,切换先按ctrl+w,然后按ctrl+j,ctrl+k
-O[N] 打开多个窗口垂直排列,切换先按ctrl+w,然后按ctrl+h,ctrl+l
+ 打开文件并将光标定位到最后一行
+<lnum> 打开文件并将光标定位到指定行,如定位到第10行+10
+/PATTERN 打开文件后光标处于第一个被匹配到PATTERN的行首,n键跳到下一个,支持正则匹配

vim多种模式
普通模式Normal: 默认模式,可以移动光标,复制粘贴删除等操作
插入模式Insert: 编辑文本
命令模式Command-line: 保存,退出,更改设置等操作
可视模式Visual: 批量选择

模式切换
ESC键退出当前模式,按两次ESC键返回到普通模式
普通模式-插入模式

1
2
3
4
5
6
i  在光标前插入
a 在光标后插入
I 在当前行首插入
A 在当前行尾插入
o 在当前行下方插入新行,注意是小写字母o
O 在当前行上方插入新行,注意是大写字母O

普通模式-命令模式

1
:CMD  格式为:号后加命令,如保存并退出命令为:wq

普通模式-可视模式

1
2
3
v  选中当前光标所在的字符,可通过方向键或hjkl键批量选择
V 选中当前光标所在的行
ctrl+v 选中当前光标所在的列,windows下的gvim可以使用ctrl+q来替换ctrl+v

可视模式-插入模式

1
c  删除当前选择的内容并切换到插入模式,即更改所选内容

普通模式下的操作命令
移动操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
h  向左移动光标
j 向下移动光标
k 向上移动光标
l 向右移动光标
w 下一个单词词首,单词分隔符可以为'空格,.-'等
e 当前或下一个单词词尾
b 当前或上一个单词词首
^ 跳转到行首的第一个非空白字符
0或Home键 跳转到行首,注意是数字零
$或End键 跳转到行尾
1G或gg 跳转到第一行
G 跳转到最后一行
H 跳转到当前页面的页首
M 页中
L 页底
zz 滚动屏幕,将光标所在行置于屏幕中间位置
#CMD 数字加命令,表示多次执行,#号表示数字,如向左移动3个字符命令为3h
#G 跳转到指定行,如跳转到第三行3G
#空格 数字加空格,光标向右移动#个字符,如向右移动三个字符3空格
#回车 数字加回车,向下移动#行,如向下移动5行5回车
# 输入字符#号本身(shift+3),匹配光标处的单词并高亮显示文件中的所有相同单词,n键跳转到下一个
/PATTERN 从上往下搜索PATTERN,支持正则,n键跳转到下一个,N键跳转到上一个
?PATTERN 从下往上搜索PATTERN
( 跳到上一句,句子以.隔开
) 跳到下一句
{ 跳到上一段,段落以空行(即回车符)隔开
} 跳到下一段
ctrl+f 向后翻一屏
ctrl+b 向前翻一屏
ctrl+d 向后翻半屏
ctrl+u 向前翻半屏
ctrl+g 在左下角显示当前光标所处位置,显示为%百分比

编辑操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
x  删除光标所在的字符
#x 删除光标之后的#个字符,#号表示数字
xp 对调光标和光标右侧字符的位置
d 删除字符或行
d$或D 删除光标所在字符到行尾
d^ 删除光标到非空行首
d0 删除光标到行首,包括行首空格
dw 删除单词或部分单词,如删除3个单词3dw
de 删除光标到单词词尾
db 删除光标到单词词首
dd 删除行,如向下删除3行3dd
d1G 删除光标所在行到第一行的所有内容
dG 删除光标所在行到最后一行的所有内容

y 复制
y$ 复制光标所在字符到行尾
y^ 复制光标到非空行首
y0 复制光标到行首,包括行首空格
yw 复制单词或部分单词
ye 复制光标到单词词尾
yb 复制光标到单词词首
yy或Y 复制行,如向下复制3行3yy
y1G 复制光标所在行到第一行的所有内容
yG 复制光标所在行到最后一行的所有内容
ya{ 复制{}的内容,包括{}本身
ya[,ya(,ya<,ya",ya' 同上

p 小写,粘贴字符到光标右侧;粘贴行到光标所在行的下一行
P 大写,粘贴字符到光标左侧,粘贴行到光标所在行的上一行
r 替换光标所在字符,如ra表示将当前字符替换为a
R 完全替换模式,ESC退出
J 将光标所在行和下一行合并为一行,用空格隔开
c 删除当前内容并切换到插入模式,即改写操作,对应操作命令c$,c^,c0,cw,ce,cb参考如上说明
cc 删除当前行并切换到插入模式
C 删除光标所在字符到行尾并切换到插入模式
u 小写,撤销操作,可以多次执行,也可以直接指定撤销次数如撤销三次3u
U 大写,撤销当前行的所有操作,注意光标不能离开当前行,否则该命令无效
ctrl+r 恢复

gu 变为小写字母
gU 变为大写字母
g~ 对调大小写字母
guu 整行变为小写字母
gUU 整行变为大写字母
g~~ 对调整行大小写字母
vip 快速选定段落
vipJ 去除换行符,显示为一行
vip> 统一段落缩进
vipd 删除选中段落
dt[标记] 删除光标到指定标记之间的内容,只支持单行标记删除,不能跨行,如删除光标到;号之间的内容dt;
di[标记] 删除标记内的全部内容,可以跨多行
dit 删除html/xml一组标签内的所有内容
di[ 删除[]中的所有内容
di{,di(,di<,di",di' 同上
cit 删除html/xml一组标签内的所有内容并切换到插入模式
ci[ 删除[]中的所有内容并切换到插入模式
ci{,ci(,ci<,ci",ci' 同上
vit 选择html/xml一组标签内的所有内容
vat 同时选择标签内的所有内容和标签本身
vi[ 选择[]中的所有内容
vi{,vi(,vi<,vi",vi' 同上
< 左缩进
> 右缩进
= 自动缩进
<< 行左缩进
>> 行右缩进
== 行自动缩进
% 跳转到匹配的括号
. 重复执行上一次操作
~ 转换大小写
zf 折叠行,按空格展开,仅在当前窗口有效.可以先通过可视模式选择想要折叠的行,然后输入zf即可.或者指定折叠的行数,如折叠20行20zf
10iyes[ESC] 快速输入10个yes,可以换成任意字符串,也可以包括特殊字符
/aaa\|bbb\|ccc 多条件搜索
/\<word\> 单词匹配

命令模式下的操作命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
:q  退出
:q! 强制退出不保存修改
:wq 保存退出
:wq! 强制保存并退出,这里需要注意文件的权限
:x 保存退出
:r f2 读取f2的文件内容到光标所在行的下一行
:w f3 另存为,将当前文件保存到另一个文件f3中
:w %.bak 另存为当前文件名.bak的备份文件
:e . 打开当前目录
:#,#w f4 将指定行保存到另一个文件中,如10,20w f4,保存第10-20行的内容到文件f4中
:!CMD 执行外部命令并显示结果,回车退出
:r!CMD 读取命令的输出到光标所在行的下一行,如果命令包含特殊字符则需要转义,如date \+\%s
:#r!CMD 输出到指定位置,#号为数字或$符号,0表示插入到文件的开头,1表示插入到第二行,$表示追加到文件的末尾
:方向键 可以上下选择vim的历史命令,操作同bash,支持的快捷键操作^w,^u,^e
:# 选择指定行,如第10行:10
:#,# 选择行的范围,如第10-20行:10,20
:#,+# 选择行的范围,如第10行和后面的10行:10,+10
:. 当前行
:$ 最后一行
:.,$-1 选择当前行到倒数第二行
:% 全文,相当于1,$
:%d 清空文件
:.$d 删除当前行到文件末尾的所有内容
:%s/aaa/bbb/gic 搜索替换,g表示全局替换,i表示忽略大小写搜索,c表示每次替换前询问
:%s/aaa/&cc/g 追加,&表示引用前面查找到的内容
:%s/a.a/name:&/g 正则搜索替换
:%s@/etc@/var@g 分隔符可以更改为其他字符,如@#+等
:%s/^/#/g 注释当前文件的所有行包括空行
:%s/./#& 注释当前文件的所有非空行,为了美观可以在#号后加一个空格
:%s/^#// 取消注释
:%s/.$/&; 在所有非空行的行尾加;号
:1s/aaa/bbb/ 替换第一行的aaa为bbb
:10,20s/^/#/g 注释当前文件的第10-20行包括空行
:10,20s/./#& 注释当前文件的第10-20行之间的非空行
:help 帮助文档,用|word|或者带有颜色的单词表示的为链接,通过ctrl+]可以跳转到相应的页面,返回Ctrl+t,退出:q
:help a 搜索指定命令帮助
:set [no]list 显示换行符$

多文件

1
2
3
4
5
6
7
8
9
$ vim f1 f2 f3
:files 显示当前所有文件列表
:next 下一个
:prev 前一个
:first 第一个
:last 最后一个
:wall 保存所有
:qall 退出所有
:wqall 保存所有并退出

多标签

1
2
3
4
5
6
7
8
9
$ vim -p3 f1 f2 f3
:tabnew 新增标签
:tabe f4 在新标签中编辑f4,支持tab补全文件名
:tabc 关闭当前的tab
:tabs 关闭所有其他的tab
:tabp 前一个tab
:tabn 后一个tab
:qa 退出所有
标签切换命令gt下一个,gT上一个

多窗口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 水平分割窗口
$ vim -o f1 f2
# 垂直分割窗口
$ vim -O f1 f2
# 单文件分割窗口
$ vim f1
:vs 水平分割窗口
:sp 垂直分割窗口
ctrl+ww 窗口切换,同Ctrl+Tab
ctrl+wh 切换到左侧窗口wh,右侧窗口wl,向下wj,向上wk
ctrl+w,s 水平分割split,注意是先按ctrl+w,松开后在按s
ctrl+w,v 垂直分割vertical
ctrl+w,q 关闭窗口
ctrl+w,o 关闭全部窗口
ctrl+w,= 让左右上下各个分屏宽度和高度均等
ctrl+w,_ 当前屏幕高度扩展到最大
ctrl+w,| 当前屏幕宽度扩展到最大
ctrl+w,c 关闭当前屏幕
:wqall 退出

普通模式下录制宏

1
2
3
4
5
qa  开始录制宏,名称为a
操作编辑...
q 停止录制
@a 运行宏a
@@ 重复执行宏

插入模式下自动补全或显示提示
输入单词的开头,然后按ctrl+p或ctrl+n,则会自动补全或显示提示
操作回退
支持以时间线来记录操作过程,方便回退和重复执行

1
2
3
:earlier 10m  回退到10分钟之前
:earlier 30s 回退到30秒之前
:later 5m 向后更新5分钟操作

历史命令
支持删除,修改和查找,回车执行对应命令

1
q:  显示历史命令,注意是q:和退出的:q正好相反

查找时忽略大小写
默认情况下 vim 的查找区分大小写

1
2
3
4
5
6
7
8
9
10
:set ic 或 :set ignorecase  忽略大小写
:set noic 或 :set noignorecase 不忽略大小写
:set ignorecase smartcase 自动识别匹配,如果搜索时无大写字母,则大小写不敏感,如果有大写字母,则大小写敏感

# 临时忽略大小写,可以用\c和\C来设置本次是否忽略大小写
/\cword 或 /word\c 忽略大小写,匹配word, Word, WORD...
/\CWord 或 /Word\C 精确匹配大小写,只匹配Word

:%s/\CWord/World/g 区分大小写替换Word为World
:%s/\cWord/World/g 不区分大小写替换word,Word,WORD,WorD...为World

vim转换tab和空格
对于已保存的文件,在vim中使用retab命令进行空格和TAB的替换,查看帮助:help retab
加%表示应用于整个文件,加!是用于处理非空白字符之后的TAB,即所有的TAB,若不加!,则只处理行首的TAB,即缩进

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
TAB替换为4个空格
:set ts=4
:set expandtab
:%retab!

TAB替换为指定空格数,指定4个空格数,即省略:set ts=4命令
:set expandtab
:%retab! 4

4个空格替换为TAB,8个空格替换为2个TAB,以此类推
:set ts=4
:set noexpandtab
:%retab!

其它相关命令
:set tabstop=4 # 设定tab宽度为4个字符
:set shiftwidth=4 # 设定自动缩进为4个字符
:set expandtab # 输入tab自动替换为4个空格,即tabstop的宽度
:set noexpandtab # 输入tab不自动替换为空格
:set list # 显示所有字符,这将显示制表符和换行符
:set nolist # 禁用

在.vimrc中添加如下配置,则后续使用vim新建的文件默认会转换tab为4个空格进行保存
set tabstop=4
set shiftwidth=4
set softtabstop=4
set expandtab

使用linux系统中的expand和unexpand命令也可以转换文件中空格和TAB

注意

在编辑过程中有可能会误按bash快捷键ctrl+s锁定输入,可以通过ctrl+q解锁,请注意是否和系统中其他快捷键冲突
需要注意锁定期间的所有输入均会在解锁之后正常输出,为了避免再次误操作,当发现输入内容不显示时先通过ctrl+q解锁,并验证当前内容是否有改动

vim官网
https://www.vim.org/
vim英文帮助
https://vimhelp.org/
vim中文社区
http://vim-china.org/
vim中文帮助
http://vimcdoc.sourceforge.net/doc/help.html
https://yianwillis.github.io/vimcdoc/doc/help.html
vim命令参考-中文
http://vimcdoc.sourceforge.net/doc/quickref.html#quickref

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 打开一个文件
$ vim file1
# 浏览目录,vim支持目录浏览,然后选择一个文件打开
$ vim dir1
# 对比两个文件
$ vim -d file1 file2
# 只读模式打开文件
$ vim -m file1
# 水平排列两个文件
$ vim -o2 file1 file2
# 垂直排列两个文件
$ vim -O2 file1 file2
# 定位到文件的第5行
$ vim +5 file1
# 定位到匹配aaa的行
$ vim +/aaa file1

使用vim和xxd工具来编辑二进制文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 以下以rev命令为例,更改Usage为Usaaa
$ cp /usr/bin/rev .
$ ./rev --help|head -1
Usage: rev [options] [file ...]
# 通过二进制方式打开文件
$ vim -b rev
# 切换为可读的十六进制
:%!xxd
# 编辑文件,先搜索Usage定位到326行,参考ASCII码表,字母a转换成十六进制后为61,然后更改左侧的十六进制码如下
326 0001450: 5573 6161 613a
# 重新转换回二进制,然后保存退出
:%!xxd -r
:wq
# 对比更改后的文件和原文件,已经有了差异differ
$ diff rev /usr/bin/rev
Binary files rev and /usr/bin/rev differ
# 再次查看帮助信息,发现Usage已经变成了Usaaa
$ ./rev --help|head -1
Usaaa: rev [options] [file ...]

# xxd其他显示格式
:%!xxd 默认为2
:%!xxd -g 1 表示每1个字节为1组
:%!xxd -g 2 表示每2个字节为1组(默认选项)
:%!xxd -g 4 表示每4个字节为1组

全局vim配置文件/etc/vimrc,用户vim配置文件~/.vimrc
自定义vimrc配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
$ more ~/.vimrc
set number
set nocompatible
set nobackup
set noswapfile
set noundofile
colorscheme desert
set shortmess=atI
set tabstop=4
set shiftwidth=4
set softtabstop=4
set expandtab
set smarttab
set autoindent
set smartindent
set noeb
set autoread
set hlsearch
set incsearch
set showmatch
set ignorecase smartcase
set pastetoggle=<F6>
syntax enable
filetype plugin indent on
autocmd FileType yaml setlocal sw=2 ts=2 et
let mapleader = ","
nmap <leader>ev :tabedit $MYVIMRC<cr>
nmap <leader><space> :nohlsearch<cr>
nmap <leader>w :w<CR>
map <F4> :w<cr>:!bash %<cr>
map <F5> :w<cr>:!python3 %<cr>
set splitbelow
set splitright
nmap <c-j> <c-w><c-j>
nmap <c-k> <c-w><c-k>
nmap <c-h> <c-w><c-h>
nmap <c-l> <c-w><c-l>

vim加载nginx配置文件语法高亮

1
2
3
4
5
6
解压缩对应版本的nginx源码包,复制以下目录到系统目录vimfiles中,并添加nginx的配置文件目录到nginx.vim文件中
cp -a contrib/vim/* /usr/share/vim/vimfiles/
echo "au BufRead,BufNewFile /usr/local/openresty/nginx/conf/* set ft=nginx" >> /usr/share/vim/vimfiles/ftdetect/nginx.vim
注意根据自己安装的nginx目录,修改上面的路径,多个路径用,隔开
然后使用vim打开nginx配置文件即可实现高亮显示关键字
vim /usr/local/openresty/nginx/conf/conf.d/www.conf

如果存在多人同时编辑同一个文件或者上一次非正常退出的文件,则会出现如下提示
[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort:
O 如果不需要再次编辑文件,只需要读取文件,则选择大写O
E 不推荐使用
R 恢复之前的编辑缓存,即恢复到上一次的编辑状态,当此次编辑完成后,需要手动删除自动生成的.swp缓存文件,否则下次依然会提示
D 如果确认上一次编辑没有必要,则可以直接删除缓存文件
Q 退出

使用vim编辑只读文件并强制保存

1
2
3
4
5
6
7
# vim编辑只读文件后强制保存,如有提示输入l然后:q退出即可保存成功
$ vim /etc/yum.conf
:w !sudo tee %
l
:q
# 推荐使用sudo vim xxx,使用vim打开只读文件时左下角有提示,加上sudo重新打开即可
$ sudo vim /etc/yum.conf

使用vim粘贴代码段时格式错乱,可以通过paste模式解决

1
2
3
4
5
6
7
8
在粘贴代码前先设置为paste模式,即取消自动缩进和连续注释,然后输入i粘贴代码
:set paste
粘贴完成后退出编辑模式,然后取消paste模式
:set nopaste
再进行正常编辑和修改即可

或者指定快捷键来切换paste模式,添加如下配置到.vimrc,使用F6键切换paste模式
set pastetoggle=<F6>

vim编辑时插入日期和时间,也可以更改为其他命令

1
2
3
4
5
6
7
8
9
:r!date  # 插入位置为当前行的下一行
:r!date \+\%s # 特殊字符需要转义
:r!date;date \+\%s # 多条命令用分号分隔
:0r!date # 在文件的开头插入
:1r!date # 在文件的第1行后面插入,即插入到第二行
:$r!date # 在文件的末尾插入,即追加到文件
:0r!date \+\#\%F-\%T-\%s # 插入时间格式为date +%F-%T-%s
:0r!date \+\#\ \%F-\%T-\%s # 空格也需要转义
# vim command :0r!date \+\#\ \%F-\%T-\%s