Linux之Vi/Vim基础使用
Author:onceday,Date:2022年9月10日
本文档主要收集整理于《鸟哥的Linux私房菜》,仅供学习交流之用。
漫漫长路,有人对你微笑过嘛…
1.引言
Linux上的文本编辑器好用的有不少,如Nano,它的快捷方式和Windows很像。其他的诸如Vim、emacs等都不错。
但问题是,在一个定制的Linux上,或者非通用的Linux里,可能不存在这类软件给我们使用。
因此,需要学习vi的使用,这个有点无奈吧…
2.Vi/Vim的使用
2.1 三种执行模式
一般命令模式,command mode:
使用vi打开一个文件时,默认就进入该模式了。
在该模式内,可以删除、复制、黏贴和浏览文件。
编辑模式,insert mode:
在一般命令模式的基础上,可以编译源文件。可通过i/I/o/O/a/A/r/R 等字符进入编辑模式,按下这些按钮时,界面左下方可能会出现INSERT 或者REPLACE 等字样。
使用ESC 即可退出该模式。
命令行模式,command-line mode:
在该模式下。主要是执行查找数据的操作,使用:,/,? 三个符号可以进入该模式。
该模式下也可进行保存、读取、退出等操作,使用ESC 即可退出该模式。
具体关系如下:
2.2 浏览类命令
这些命令中部分可搭载数字使用,用于指定列数或行数。
快捷键 | 描述 |
---|
h ,← | 20←代表左移动10个字符 | j ,↓ | 向下移动字符 | k ,↑ | 向上移动字符 | l ,→ | 向右移动字符 | Ctrl+f | 向下移动一页,相当于Page down | Ctrl+b | 向上移动一页,相当于Page up | Ctrl+d | 向下移动半页 | Ctrl+u | 向上移动半页 | + | 光标移动到非空格符的下一行 | - | 光标移动到非空格符的上一行 | n<space> | 如20+sapce,则光标向右移动这一行的n个字符 | 0,home | 移动到这一行的最前面字符处 | $,end | 移动到这一行的最后面字符处 | H | 移动到界面显示的最上面一行的第一个字符 | M | 移动到这个屏幕的中央一行的第一个字符 | L | 移动到屏幕最下面一行的第一个字符 | G | 移动到这个文件的最后一行 | [n]G | 10G,移动到这个 文件的第n行 | gg | 移动到这个文件的第一行 | n+Enter | 光标向下移动n行 |
2.3 查找和替换
命令 | 描述 |
---|
/word | 向光标之下寻找一个名称为word的字符串 | ?word | 向光标之上寻找一个字符串名称为word的字符串 | n | 按键,代表重复前一个查找的操作,方向和前一个查找相同 | N | 按键,代表重复下一个查找的操作,方向和下一个查找相同 |
使用示例如下:
:/n1,n2s/word1/word2/g
上面表示在n1行和n2行之间,查找word1这个字符串,并将该字符串转化为word2这个字符串。
:1,$s/word1/word2/g
上面表示在第一行到最后一行寻找word1字符串,并将该字符串替换为word2。
:1,$s/word1/word2/gc
从第一行到最后一行寻找word1字符串,并将该字符串替换为word2,且在替换前显示提示字符给用户确认(confirm)是否需要替换。
2.4 删除,复制,粘贴
命令 | 描述 |
---|
x,X | x为向后删除一个字符(del),X为向前删除一个字符(Backspace)。 | nx | n为数字,连续向后删除n个字符。10x即连续删除10个字符 | dd | 删除(剪切)光标所在的一整行 | ndd | 删除(剪切)光标所在的向下n行,例如20dd则是删除(剪切)20行 | d1G | 删除(剪切)光标所在行到第一行的所有数据 | dG | 删除(剪切)光标所在行到最后一行的所有数据 | d$ | 删除(剪切)光标所在处到该行的最后一个字符 | d0 | 删除光标所在处到该行的最前面一个字符 | yy | 复制光标所在的那一行 | nyy | n为数字,复制光标所在的向下n行,例如20yy则是复制20行。 | y1G | 复制光标所在行到第一行的所有数据 | yG | 复制光标所在行到最后一行的所有数据 | y0 | 复制光标所在的哪一个字符到该行行首的所有数据 | y$ | 复制光标所在的那个字符到该行行尾的所有数据 | p与P | p为将已复制的数据在光标下一行粘贴,P则为粘贴在光标上一行。 | J | 将光标所在行与下一行的数据结合成同一行 | c | 重复删除多个数据,例如向下删除10行,[10cj] | u | 恢复前一个操作 | Ctrl+r | 重做上一个操作 | . | 重复前一个操作 |
2.5 从命令模式切换到编辑模式
命令 | 描述 |
---|
i与I | 进入插入模式,i从目前光标所在处插入,I为目前所在行的第一个非空格符处开始插入 | a与A | 进入插入模式,a为从目前光标所在的下一个字符处开始插入,A为从光标所在行的最后一个字符处开始插入 | o与O | 进入插入模式,o在目前光标所在的下一行处插入新的一行,O为在目前光标所在处的上一行插入新一行 | r与R | 进入替换模式,r只会替换光标所在的那一个字符一次,R会一直替换光标所在的文字,直至按下Esc为止。 | Esc | 退出编辑模式,回到一般命令模式中 |
2.6 命令行模式可用的命令
命令 | 描述 |
---|
:w | 将编辑的数据写入到磁盘文件中 | :w! | 若文件属性为只读时,强制写入该文件。注意需要具有写入的权限。 | :q | 退出vi | :q! | 若层修改过该文件,又不想保存,使用!为强制退出不保存。 | :wq | 保存后退出 | :wq! | 强制保存后退出 | ZZ | 若文件没有修改,则不保存退出,若文件已被修改过,则保存后退出。 | :w [filename] | 将编辑的数据保存为另一个文件 | :r [filename] | 在编辑的数据中,读入另一个文件的数据,亦即将filename这个文件的内容加到光标所在行的后面 | :n1,n2 w [filename] | 将n1到n2 的内容保存为filename的这个文件 | :! command | 暂时退出vi到命令行模式下执行command的显示结果。如[:! ls /home]即可在vi中查看/home下面以ls输出的文件信息。 | :set nu | 显示行号,设置之后,会在每一行的前缀显示该行的行号 | :set nonu | 取消行号设置 |
2.7 缓存和恢复
使用Vi编辑的时候,Vim会在被编辑的目录下,在建立一个名为.filename.swap的文件。当系统崩溃时,Vi即可利用该缓存中内容来回复内容。
E325: ATTENTION
Found a swap file by the name ".hello.c.swp"
owned by: onceday dated: Sun Sep 11 12:37:34 2022
file name: ~onceday/hello.c
modified: YES
user name: onceday host name: LAPTOP-JUN9BRPR
process ID: 114
While opening file "hello.c"
dated: Tue Oct 12 10:00:09 2021
(1) Another program may be editing the same file. If this is the case,
be careful not to end up with two different instances of the same
file when making changes. Quit, or continue with caution.
(2) An edit session for this file crashed.
If this is the case, use ":recover" or "vim -r hello.c"
to recover the changes (see ":help recovery").
If you did this already, delete the swap file ".hello.c.swp"
to avoid this message.
Swap file ".hello.c.swp" already exists!
[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort:
当Vi的工作被不正常的中断时,就会出现上述的这些情况:
指令 | 描述 |
---|
[O]pen Read-Only | 打开此文件成为只读文件,只是查看该文件而不编辑该文件,在多人编辑时也会出现该情况。 | [E]dit anywhere | 正常方式打开要编辑的那个文件,并不会加载缓存的内容,容易出现多个用户互相改变对方文件的问题。 | [R]ecover | 加载缓存的内容,用于救回之前未保存的工作,不过当你救回来 | [D]elete it | 如果确认缓存无用,那么再打开文件之前会将这个缓存删除。 | [Q]uit | 按下q就退出Vim,不会进行任何操作就回到命令提示符 | [A]bort | 忽略这个编辑操作,然后回到命令提示符。 |
3.Vim的额外功能
如果在界面的右下角有显示目前光标所在行的行号,那么此时所用的就是Vim。
VIm会对打开的文档作额外的语法校验,它支持很多编程语言和配置文件的语法。
3.1 可视区块(Visual Block)
按键如下:
命令 | 描述 |
---|
v | 字符选择,会将光标经过的地方反白选择 | V | 行选择,会将光标经过的行反白选择 | Ctrl+v | 可视区块,可以用矩形的方式选择数据 | y | 将反白的地方复制起来 | d | 将反白的地方删除掉 | p | 将刚刚复制的区块,在光标所在处粘贴 |
通过反白选择的区域可以直接复制粘贴整个区块。
3.2 多文件编辑
可以同时打开多个文件:
Vim file1 file2 file3 file4 ......
然后可使用下面命令进行切换:
命令 | 描述 |
---|
:n | 编辑下一个文件 | :N | 编辑上一个文件 | :files | 列出目前这个vim开启的所有文件 |
3.3 多窗口功能
在命令行模式可通过以下命令来执行多窗口相关的操作:
命令 | 描述 |
---|
:sp [filename] | 打开一个新窗口,如果加有filename,表示在新窗口创建一个新文件.否则表示两个窗口为同一个文件内容。 | Ctrl+w+j/↓ | 先按下Ctrl,再按下w,然后释放所有按键,再按下j/↓,则光标移向下方的窗口 | Ctrl+w+k/↑ | 按键步骤同上,光标移动到上面的窗口 | Ctrl+w+q | 关闭窗口,也可以通过:q 和:close |
3.4 关键词补齐功能
注意,在WindTerm的终端模式为Xterm下,无法支持Ctrl+[A-Z]等组合键,因此可以切换为VT520终端模式。
使用以下命令:
组合键 | 补齐的内容 |
---|
ctrl+x ->ctrl+n | 通过目前正在编辑的这个文件的内容文字作为关键词,予以补齐。 | ctrl+x ->ctrl+f | 以当前目录内的文件名作为关键词,予以补齐。 | ctrl+x ->ctrl+o | 以扩展名作为语法补充,以Vim内置的关键词补齐 |
4.Vim额外的注意事项
4.1 操作记录
在以下文件记录了vim的操作:
~/.viminfo
可以用来查询曾经做过的操作。
4.2 设置环境记录
可在一般命令模式下,可使用:set all 查看目前所有的环境参数设置情况。
可以看到是非常多的。
整个环境变量的设置放在以下文件夹(版本不同位置可能不一样):
/etc/vimrc
/etc/vim/vimrc
4.3 中文编码问题
需要注意以下四种编码:
- Linux默认支持的语系数据,这与/etc/locale.conf
- 终端bash的语系:这与LANG,LC_ALL这几个变量有关
- 文件原本的编码
- 打开终端的软件
Linux的终端tty1-tty6不支持中文编码,而终端bash等的编码可通过以下方式更改:
LANG=zh_CN.gbk
export LC_ALL=zh_CN.gbk
4.4 换行符
在windows的换行符为/r/n 即^M$ ,CRLF。
在Linux的换行符为$ ,即LF。
4.5 转换编码iconv
可使用iconv 来转换编码:
Usage: iconv [OPTION...] [FILE...]
Convert encoding of given files from one encoding to another.
Input/Output format specification:
-f, --from-code=NAME encoding of original text
-t, --to-code=NAME encoding for output
Information:
-l, --list list all known coded character sets
Output control:
-c omit invalid characters from output
-o, --output=FILE output file
-s, --silent suppress warnings
--verbose print progress information
-?, --help Give this help list
--usage Give a short usage message
-V, --version Print program version
Mandatory or optional arguments to long options are also mandatory or optional
for any corresponding short options.
一般以下使用即可:
iconv -f utf-8 -t gbk filename -o new-filename
-f 是指定原来的编码,-t 是新的编码,-o 指定输出的新文件名字。
如果不指定具体文件,将输出到stdout ,在终端模式下,即为命令行本身。
|