4.3 vi编辑器
Linux系统中的很多功能都需要通过修改相应的配置文件来实现,在字符界面下要修改文件的内容大都要用到vi编辑器,它可以执行输出、删除、查找、替换、块操作等众多文本操作,而且用户可以根据自己的需要对其进行定制,这是其他编辑程序所没有的。vi编辑器就相当于Windows系统中的Word+记事本软件,只是写的代码文件后缀名是.c或.cpp,它在Linux系统中的地位非常重要。vim是vi编辑器的增强版本,在vi编辑器的基础上扩展了很多实用的功能,但是习惯上也将vim称作vi。
vi编辑器本身的命令很简单,命令的基本格式为:
vim [文件名]
如果指定的文件不存在,那么vim命令会创建文件并进入编辑状态;如果文件存在,则进入编辑状态对其进行编辑。
4.3.1 vi编辑器的工作模式
vi编辑器界面有三种不同的工作模式:命令模式、输入模式和末行模式。
1.命令模式
任何时候,不管用户处于何种模式,只要按一下Esc键,即可使vi进入命令行模式。当在shell环境下输入vi命令启动vi编辑器时,也是处于该模式下。
在该模式下用户可以输入各种合法的vi命令用于管理自己的文档。此时,从键盘上输入的任何字符都被当作编辑命令来解释。若输入的字符是合法的vi命令,则vi在接受用户命令之后完成相应的动作(需注意的是所输入的命令并不在屏幕上显示出来)。若输入的字符不是vi的合法命令,vi会响铃提出警报。
2.输入模式
在命令模式下输入插入命令i、附加命令a、打开命令o、修改命令c、取代命令r或替换命令s都可以进入到文本输入模式。在该模式下,用户输入的任何字符都被vi当做文件内容保存起来,并将其显示在屏幕上。在文本输入过程中,若想回到命令模式下,按Esc键即可。
3.末行模式
也称ex转义模式。Linux vi命令和Ex编辑器的功能是相同的,二者的主要区别是用户界面。在vi中,命令通常是单个键,例如i、a、o等;而在Ex中,命令是以按Enter键结束的正文行。Linux vi命令有一个专门的“转义”命令,可访问很多面向行的Ex命令。在命令模式,用户按“:”键即可进入末行模式,此时Linux vi命令会在显示窗口的最后一行(通常也是屏幕的最后一行)显示一个“:”作为末行模式的提示符,等待用户输入命令。多数文件管理命令都是在此模式下执行的(如把编辑缓冲区的内容写到文件中等)。末行命令执行完成后,:Linux vi命令自动回到命令模式。例如:输入
:1,$s / A / a / g
则从文件第一行至文件尾将大写A全部替换成小写a。
若在末行模式下输入命令过程中改变了主意,可用退格键将输入的命令全部删除之后,再按一下退格键,即可使Linux vi命令回到命令模式下。如果要从命令模式转换到编辑模式,可以输入命令a或者i;如果需要从输入模式返回,则按Esc键即可。在命令模式下输入“:”即可切换到末行模式,然后输入命令。
4.3.2 vi的使用方法
vi编辑器中涉及到的命令和快捷键非常多,下面以一个具体的实例来介绍一些常用的操作。
将系统中的/etc/inittab文件复制到/root目录中,以它为对象用vi编辑器进行编辑。
[root@localhost ~]# cp /etc/inittab /root [root@localhost ~]# vim inittab
1.命令模式下的基本操作
(1)移动光标
要对正文内容进行修改,首先必须把光标移到指定位置,具体操作如表4-11所示。
表4-11 光标移动操作快捷键
为了便于查看行间跳转效果,可以先进入末行模式执行“:set nu”命令显示行号,然后输入“1G”或“gg”跳转到第1行,使用“G”可以跳转到最后一行,使用“3G”可以跳转到第3行,“5G”跳转到第5行等。按^键或数字键0,可以将光标移动到所在行的行首。按$键或End键,可以将光标移动到所在行的行尾。先后按“10”+“→”,可以将光标向右移动10个字符;先后按下“10”+“←”,可以将光标向左移动10个字符。
(2)复制、粘贴和删除
复制、粘贴和删除的快捷键可概括为如表4-12所示。
表4-12 复制、粘贴和删除操作快捷键
以用其他字符来替换光标所指向的字符,或从当前光标位置删除一个或多个字符为例,当执行操作后从正文中删除的内容(如字符、字或行)并没有真正丢失,而是被剪切并复制到了一个内存缓冲区中,用户可将其粘贴到正文中的指定位置。
(3)文件内容查找
要查找文件中指定字或短语出现的位置,可以用vi直接进行搜索,而不必以手工方式,具体操作如表4-13所示。
表4-13 文件内容查找操作快捷键
在命令模式下,按“/”键后输入指定的字符串,将从当前光标处开始向后进行查找。例如输入“/runlevel”,按Enter键后将查找文件中的“runlevel”字符串并高亮显示结果。光标自动移动到第一个查找结果处,输入“n”移动到下一个查找结果,输入“N”移动到上一个查找结果。输入“?”可以自当前光标处开始向上查找,用法与“/”类似。
(4)撤销编辑
在编辑文档的过程中,为消除某个错误的编辑命令造成的后果,可以使用撤销命令。如果用户希望在新的光标位置重复前面执行过的编辑命令,可用重复命令的方法操作,具体操作方法如图4-14所示。
表4-14 撤销操作快捷键
输入“u”可以撤销最近一次操作,并恢复操作结果,输入“U”可以撤销对当前行所做的所有编辑。
(5)文本选中
vi可进入到一种称为Visual的模式,在该模式下,用户可以用光标移动命令可视地选择文本,然后再执行其他编辑操作,例如删除、复制等。其操作功能如表4-15所示。
表4-15 文本选中操作快捷键
2.输入模式下的基本操作
在命令模式下,正确定位光标后,可用以下命令切换到输入模式。操作命令如表4-16所示。
表4-16 插入模式切换操作快捷键
上面介绍了几种切换到插入模式的简单方法。此外还有一些命令,它们允许在进入插入模式之前首先删去一段正文,从而实现正文的替换。这些操作命令如表4-17所示。
表4-17 替换操作快捷键
3.末行模式下的基本操作
在命令模式下输入“:”可以切换到末行模式,vi编辑器的最后一行将显示“:”提示符,用户可以在该提示符后输入特定的末行命令。
(1)保存并退出vi编辑器
具体操作命令如表4-18所示。
表4-18 vi编辑器保存并退出操作快捷键
命令“:w”可以保存文件内容,如需要另存为其他文件,则需要指定新的文件名,“:w /root/newfile”。
命令“:q”可以退出vi编辑器,“:q!”可以不保存并强制退出。“:wq”保存修改并退出。
(2)文件内容替换
具体操作命令如表4-19所示。
表4-19 文件内容替换操作快捷键
从上述替换命令可以看到:“g”放在命令末尾,表示对所有搜索到的字符串进行替换;命令中不加“g”,表示只对首次搜索到的字符串进行替换;“g”放在命令开头,表示对正文中所有包含搜索字符串的行进行替换操作。“s/old/new/4”的功能是从当前行开始将4行内的“old”替换成“new”;而“s/old/new/”的功能是从当前行开始将“old”替换成“new”。
4.shell切换
在编辑正文时,利用vi命令模式下提供的shell切换命令,无须退出vi即可执行Linux命令,十分方便,这也可以说是末行模式。语法格式为:
:! Command
执行完shell命令Command后回到vi。另外,在编辑模式下,输入“K”,可命令vi查找光标所在单词的手册页,相当于运行man命令。
vi编辑器看似很复杂,其实常用的操作只有几个,而且同样的一个操作往往有好几种不同的实现方法,至于到底用哪种方法,则完全可以凭个人的喜欢。下面是使用vi编辑器的几个例子,如果读者能熟练完成,那么对vi编辑器也就掌握得差不多了。
【例4-4】 vi编辑器常用操作练习。
(1)在/root目录下建立一个名为vitest的目录。
mkdir /root/vitest
(2)将文件/etc/man.config复制到/root/vitest目录中。
cp /etc/man.config /root/vitest
(3)使用vi编辑器打开文件/root/vitest/man.config,以便对其进行编辑。
vim /root/vitest/man.config
(4)在vi编辑器中设定行号。
:set nu
(5)移动光标到第58行,再向右移动40个字符,说出现在看到的双引号内是什么目录?
先按下“58G”,再按下“40”+“→”,会看到“/dir/bin/foo”。
(6)移动光标到第一行,并且向下搜寻“X11R6”这个字符串,请问它在第几行?
先按下“gg”,然后按下“/X11R6”搜寻,会看到它在第47行。
(7)将50到100行之间的“man”改为“MAN”,并且一个一个地确认是否需要修改。
:50,100 s/man/MAN/gc
(8)修改完之后,突然反悔了,要全部复原,有哪些方法?
简单的方法是可以一直按下u键命令恢复到原始状态,或使用不储存离开命令“:q!”。
(9)复制第51到第60行这10行的内容,并且粘贴到最后一行之后。
先按下“51G”,然后再按下“10yy”,之后按下G键,光标到最后一行,再按下p键粘贴上这 10行。
(10)删除第11到30行之间的20行。
按下“11G”之后,再按下“20dd”即可删除这20行了。
(11)将这个文件在当前目录下另存成一个名为man.test.config的文件。
:w man.test.config
(12)移到第29行,并且删除15个字符。
按下“29G”之后,再按下“15x”即可删除15个字符。
(13)保存后退出。
:wq!
(14)将整个文档中所有的“runlevel”都替换成“level”。
:% s/runlevel/level/g