第10章 vim程序编辑器
系统管理员的重要工作就是修改与设置某些重要软件的配置文件,因此至少得要学会一种以上的命令行界面的文本编辑器。在所有的 Linux distributions 上头都会有的一套文本编辑器就是vi,而且很多软件默认也是使用vi作为它们编辑的界面,因此笔者建议你务必要学会使用vi这个强大的文本编辑器。此外,vim是高级版的vi,vim不但可以用不同颜色显示文字内容,还能够进行诸如shell脚本,C等程序编辑功能,你可以将vim视为一种程序编辑器。鸟哥也是用vim编辑鸟站的网页文章呢!
10.1 vi 与vim
由前面一路走来,我们一直建议使用文本模式来处理Linux的系统设置问题,因为不但可以让你比较容易了解到Linux的运行状况,也比较容易了解整个设置的基本思想,更能保证你的修改可以顺利被运行。所以,在Linux的系统中使用文本编辑器来编辑你的Linux参数配置文件可是一件很重要的事情。因此系统管理员至少应该要熟悉一种文本编辑器。
再次强调,不同的 Linux distribution 各有其不同的附加软件,例如 Red Hat Enterprise Linux 与 Fedora 的 ntsysv 与 setup 等,而 SuSE 则有 YAST 管理工具等, 因此,如果你只会使用此种类型的软件来控制你的 Linux 系统时,当接管不同的 Linux distributions 时,就会茫然失措。
在Linux的世界中,绝大部分的配置文件都是以ASCII的纯文本形式存在,因此利用简单的文字编辑软件就能够修改设置了。与微软的Windows系统不同的是,如果你用惯了Microsoft Word或Corel Wordperfect 的话,那么除了 X Window 里面的图形界面编辑程序(如 Emacs)用起来尚可应付外,在Linux的文本模式下,会觉得文本编辑程序都没有图形界面来得直观与方便。
什么是纯文本文件?其实文件记录的就是 0 与 1 ,而我们通过编码系统来将这些 0与 1 转成我们认识的文字就是了。 在第0 章里面的数据表示方式有较多说明,请自行查阅, ASCII 就是其中一种广为使用的文字编码系统,ASCII 系统中的图标与代码可以参考 http://zh.wikipedia.org/wiki/ASCII。
那么 Linux 在命令行界面下的文本编辑器有哪些呢?其实有非常多。经常听到的就有 Emacs, pico,nano,joe,与 vim 等 [1]。既然有这么多命令行界面的文本编辑器,那么我们为什么一定要学vi?还有那个vim是做啥用的?下面就来谈一谈先。
10.1.1 为何要学 vim
文本编辑器那么多,我们之前在第5章也曾经介绍过那简单好用的nano,既然已经学会了nano,干吗鸟哥还一直要你学这不是很友善的vi呢?其实是有原因的。因为:
所有的UNIX Like 系统都会内置vi 文本编辑器,其他的文本编辑器则不一定会存在;
很多软件的编辑接口都会主动调用vi(例如后来会谈到的crontab,visudo,edquota 等命令);
vim具有程序编辑的能力,可以主动以字体颜色辨别语法的正确性,方便程序设计;
程序简单,编辑速度相当快速。
其实重点是上述的第二点,因为有太多Linux上面的命令都默认使用vi作为数据编辑的接口,所以你必须要学会vi,否则很多命令你根本就无法操作。这样说,有刺激到你务必要学会vi的热情了吗?
那么什么是vim呢?其实你可以将vim视作vi的高级版本,vim可以用颜色或底线等方式来显示一些特殊的信息。举例来说,当你使用vim去编辑一个C程序语言的文件,或者是我们后续会谈到的shell script 程序时,vim 会依据文件的扩展名或者是文件内的开头信息判断该文件的内容而自动调用该程序的语法判断式,再以颜色来显示程序代码与一般信息。也就是说,这个vim是个“程序编辑器”。甚至一些Linux基础配置文件内的语法,都能够用vim来检查,例如我们在第8章谈到的/etc/fstab这个文件的内容。
简单来说,vi 是老式的文字处理器,不过功能已经很齐全了,但是还是有可以进步的地方。vim则可以说是程序开发者的一项很好用的工具,就连 vim 的官方网站(http://www.vim.org)自己也说vim是一个“程序开发工具”而不是文字处理软件。因为vim里面加入了很多额外的功能,例如支持正则表达式的查找架构、多文件编辑、块复制等。这对于我们在Linux上面进行一些配置文件的修订工作时是很棒的一项功能。
什么时候会使用到 vim 呢?其实鸟哥的整个网站都是在 vim 的环境下一字一字地搭建起来的。早期鸟哥使用网页制作软件编写网页,但是老是发现网页编辑软件都不怎么友善,尤其是写到 PHP 方面的程序代码时。后来就干脆不使用别的编辑软件,直接使用vim ,然后标签 (tag) 也都自行用键盘输入。这样整个文件也比较干净。所以说,鸟哥我是很喜欢 vim 的。
下面会先就简单的vi做个介绍,然后再跟大家报告一下vim的功能与用法。
10.2 vi 的使用
基本上vi共分为3种模式,分别是一般模式、编辑模式与命令行模式。这3种模式的作用分别如下。
一般模式
以 vi 打开一个文件就直接进入一般模式了(这是默认的模式)。在这个模式中,你可以使用上下左右按键来移动光标,你可以删除字符或删除整行,也可以复制、粘贴你的文件数据。
编辑模式
在一般模式中可以进行删除、复制、粘贴等的操作,但是却无法编辑文件内容的。要等到你按下“i,I,o,O,a,A,r,R”等任何一个字母之后才会进入编辑模式。通常在Linux中,按下这些按键时,在界面的左下方会出现INSERT或REPLACE的字样,此时才可以进行编辑。而如果要回到一般模式时,则必须要按下【Esc】这个按键即可退出编辑模式。
命令行模式
在一般模式当中,输入“:、/、? ”3 个中的任何一个按钮,就可以将光标移动到最下面那一行。在这个模式当中,可以提供你查找数据的操作,而读取、保存、大量替换字符、离开vi、显示行号等的操作则是在此模式中完成的。
简单地说,我们可以将这3个模式想成下面的图来表示,如图10-1所示。
图10-1 vi3 种模式的相互关系
注意到上面的图标,你会发现一般模式与编辑模式及命令行模式可互相切换,但编辑模式与命令行模式之间不可互相切换。这非常重要。我们下面以一个简单的例子来进行说明。
10.2.1 简单执行范例
如果你想要使用vi来新建一个名为test.txt的文件时,你可以按如下介绍做。
1.使用vi进入一般模式
[root@www ~]# vi test.txt
直接输入“vi文件名”就能够进入vi的一般模式了。请注意,记得vi后面一定要加文件名,不管该文件名存在与否。整个界面主要分为两部分,上半部与最下面一行两者可以视为独立的。如图10-2所示,图中那个虚线是不存在的,是用来说明而已。上半部显示的是文件的实际内容,最下面一行则是状态显示行(如[New File]信息),或者是命令执行行。
如果你打开的文件是旧文件(已经存在的文件),则可能会出现如图10-3所示的信息。
图10-2 用vi 打开一个新文件
图10-3 用vi打开一个旧文件
如图 10-3 所示,箭头所指的那个“"/etc/man.config" 141L,4617C”代表的是文件名为/etc/man.conf,文件内有 141 行以及具有 4617 个字符的意思。那一行的内容并不是在文件内,而是vi显示一些信息的地方。此时是在一般模式的环境下。接下来开始来输入。
2.按下i进入编辑模式,开始编辑文字
在一般模式之中,只要按下 i,o,a 等字符就可以进入编辑模式了。在编辑模式当中,你可以发现在左下角状态栏中会出现–INSERT-的字样,那就是可以输入任意字符的提示。这个时候,键盘上除了[Esc]这个按键之外,按下其他的按键都可以视作为一般的输入了,所以你可以进行任何的编辑,如图10-4所示。
在 vi 里面, [Tab] 键所得到的结果与空格符所得到的结果是不一样的,特别强调一下。
3.按下[Esc]键回到一般模式
好了,假设我已经按照上面的样式给他编辑完毕了,那么应该要如何退出呢?就是按下[Esc]即可。马上你就会发现界面左下角的–INSERT–不见了。
4.在一般模式中输入“: wq”保存后离开vi
OK,我们要存档了,保存并离开的命令很简单,输入“:wq”即可保存离开。(注意了,按下:该光标就会移动到最下面一行去。)这时你在提示符后面输入“ls-l”即可看到我们刚才新建的test.txt文件。整个显示如图10-5所示那样。
图 10-4 开始用vi 来进行编辑
图10-5 保存并离开vi环境
如此一来,你的文件test.txt就已经创建起来了。需要注意的是,如果你的文件权限不对,例如为-r—r—r—时,那么可能会无法写入,此时可以使用“强制写入”的方式吗?可以。使用“:wq!”多加一个感叹号即可。不过,需要特别注意。那个是在你的权限可以改变的情况下才能成立的。关于权限的概念,请自行回去翻一下第6章的内容。
10.2.2 按键说明
除了上面简易范例的I、[Esc]、:wq之外,其实vim还有非常多的按键可以使用。在介绍之前还是要再次强调,vim 的三种模式只有一般模式可以与编辑、命令行模式切换,编辑模式与命令行模式之间并不能切换的。这点在图10-2里面已介绍过。下面就来谈谈vim中会用到的按键功能。
第一部分:一般模式可用的按钮说明,光标移动、复制粘贴、查找替换等,如表10-1所示。
表10-1
罉裄
罉裄
第二部分:一般模式切换到编辑模式的可用的按钮说明
第三部分:一般模式切换到命令行模式的可用的按钮说明
罉裄
特别注意,在 vi 中,数字是很有意义的。数字通常代表重复做几次的意思。也有可能是代表去到第几个什么什么的意思。举例来说,要删除50行,则是用“50dd”对。数字加在操作之前,那我要向下移动20行呢?那就是“20j”或者是“20↓”即可。
会这些命令就已经很厉害了,因为常用到的命令也只有不到一半。通常 vi 的命令除了上面注明的常用的几个外,其他是不用背的,你可以做一张简单的命令表在你的屏幕上,一有疑问可以马上查询。这也是当初鸟哥使用vim的方法。
10.2.3 一个案例练习
赶紧测试一下你是否已经熟悉 vi 这个命令呢?请依照下面的需求进行命令操作。(下面的操作为使用 CentOS 5.2 中的 man.config 来做练习的,该文件你可以在这里下载:http://linux.vbird.org/linux_basic/0310vi/man.config。)看看你的显示结果与笔者的结果是否相同。
1.请在/tmp这个目录下新建一个名为vitest的目录。
2.进入vitest这个目录当中。
3.将/etc/man.config复制到本目录下面(或由上述的链接下载man.config文件)。
4.使用vi打开本目录下的man.config这个文件。
5.在vi中设置一下行号。
6.移动到第58行,向右移动40个字符,请问你看到的双引号内是什么目录?
7.移动到第一行,并且向下查找一下“bzip2”这个字符串,请问它在第几行?
8.接着下来,我要将50到100行之间的“man”改为“MAN”,并且一个一个挑选是否需要修改,如何执行命令?如果在挑选过程中一直按“y”,结果会在最后一行出现改变了几个 man呢?
9.修改完之后,突然反悔了,要全部复原,有哪些方法?
10.复制65到73这九行的内容(含有MANPATH_MAP),并且粘贴到最后一行之后。
11.21到42行之间的开头为“#”符号的批注数据我不要了,要如何删除?
12.将这个文件另存成一个man.test.config的文件名。
13.去到第27行,并且删除15个字符,结果出现的第一个字符是什么?
14.在第一行新增一行,该行内容输入“Iam a student…”。
15.保存后离开。
整个步骤可以的显示结果如下:
1.“mkdir /tmp/vitest”
2.“cd /tmp/vitest”
3.“cp /etc/man.config .”
4.“vi man.config”
5.“:set nu”,然后你会在界面中看到左侧出现数字即为行号。
6.先按下“58G”再按下“40→”会看到“/dir/bin/foo”这个字样在双引号内。
7.先执行“1G”或“gg”后,直接输入“/bzip2”,则会去到第118行才对。
8.直接执行“:50,100s/man/MAN/gc”即可。若一直按“y”最终会出现“在23行内替换25个字符串”的说明。
9.简单的方法可以一直按“u”回复到原始状态,或者使用不存储离开“:q!”之后,再重新读取一次该文件。
10.输入“65G”,然后再输入“9yy”,之后最后一行会出现“复制九行”之类的说明字样。按下“G”到最后一行,再按“p”粘贴九行。
11.因为21~42行共22行,因此用“21G”→“22dd”就能删除22行,此时你会发现光标所在21行的地方变成MANPATH开头,批注的“#”符号那几行都被删除了。
12.“:w man.test.config”,你会发现最后一行出现"man.test.config" [New]..的字样。
13.输入“27G”之后,再输入“15x”即可删除15个字符,出现“you”的字样。
14.先输入“1G”去到第一行,然后按下大写的“O”便新增一行且在插入模式;开始输入“I am a student…”后,按下[Esc]回到一般模式等待后续工作。
15.输入“:wq”。
如果你的结果都可以查得到,那么vi的使用上面应该没有太大的问题。剩下的问题就是多打字练习。
10.2.4 vim 的保存文件、恢复与打开时的警告信息
目前主要的编辑软件都会有“恢复”的功能,也即当你的系统因为某些原因而导致类似死机的情况时,还可以通过某些特别的机制来让你将之前未保存的数据“救”回来。这就是笔者这里所谓的“恢复”功能。那么vim有没有恢复功能呢?vim就是通过“保存文件”来挽回数据的。
当我们在使用vim编辑时,vim会在被编辑的文件的目录下再新建一个名为.filename.swp的文件。例如我们在上一个小节谈到的编辑/tmp/vitest/man.config 这个文件时, vim 会主动创建/tmp/vitest/.man.config.swp 的暂存文件,你对man.config 做的操作就会被记录到这个.man.config.swp 当中。如果你的系统因为某些原因断线了,导致你编辑的文件还没有保存,这个时候.man.config.swp 就能够发挥救援的功能了。我们来测试一下。下面的练习有些部分的命令我们尚未谈到,没关系,你先照着做,后续再回来了解。
[root@www ~]# cd /tmp/vitest
[root@www vitest]# vim man.config
此时会进入到 vim 的界面,请在 vim 的一般模式下按下[ctrl]-z的组合键
[1]+ Stopped vim man.config <==按下 [ctrl]-z 会告诉你这个信息
当我们在vim 的一般模式下按下[ctrl]-z 的组合键时,你的vim会被丢到后台去执行。这部分的功能我们会在第 17 章的程序管理当中谈到,你这里先知道一下即可。回到命令提示符后,接下来我们来模拟将vim的工作不正常的中断。
[root@www vitest]# ls -al
total 48
drwxr-xr-x 2 root root 4096 Jan 12 14:48 .
drwxrwxrwt 7 root root 4096 Jan 12 13:26 ..
-rw-r—r— 1 root root 4101 Jan 12 13:55 man.config
-rw-r—r— 1 root root 4096 Jan 12 14:48 .man.config.swp <==就是它,暂存文件
-rw-r—r— 1 root root 4101 Jan 12 13:43 man.test.config
[root@www vitest]# kill -9 %1 <==这里模拟断线停止 vim 工作
[root@www vitest]# ls -al .man.config.swp
-rw-r—r— 1 root root 4096 Jan 12 14:48 .man.config.swp <==暂存文件还是会存在
那个kill可以模拟将系统的vim工作删除的情况,你可以假装死机了。由于vim的工作被不正常中断,导致暂存盘无法通过正常流程来结束,所以暂存文件就不会消失,而继续保留下来。此时如果你继续编辑那个man.config,会出现什么情况呢?会出现如下所示的状态:
[root@www vitest]# vim man.config
E325: ATTENTION <==错误代码
Found a swap file by the name ".man.config.swp" <==下面数行说明有暂存文件的存在
owned by: root dated: Mon Jan 12 14:48:24 2009
file name: /tmp/vitest/man.config <==这个暂存盘属于哪个实际的文件?
modified: no
user name: root host name: www.vbird.tsai
process ID: 11539
While opening file "man.config"
dated: Mon Jan 12 13:55:07 2009
下面说明可能发生这个错误的两个主要原因与解决方案。
(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 man.config"
to recover the changes (see ":help recovery").
If you did this already, delete the swap file ".man.config.swp"
to avoid this message.
Swap file ".man.config.swp" already exists!下面说明你可进行的操作
[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort:
由于暂存盘存在的关系,因此vim会主动判断你的这个文件可能有些问题,在上面的图示中vim提示两点主要的问题与解决方案,分别是这样的:
问题一:可能有其他人或程序同时在编辑这个文件。
由于Linux是多人、多任务的环境,因此很可能有很多人同时在编辑同一个文件。如果在多人共同编辑的情况下,万一大家同时保存,那么这个文件的内容将会变得乱七八糟。为了避免这个问题,因此vim会出现这个警告窗口。解决的方法则是:
找到另外那个程序或人员,请他将该vim的工作结束,然后你再继续处理。
如果你只是要看该文件的内容并不会有任何修改编辑的行为,那么可以选择打开成为只读(O)文件,即上述界面反白部分输入英文“o”即可,其实就是[O]pen Read-Only 的参数。
问题二:在前一个vim的环境中,可能因为某些不明原因导致vim中断(crashed)。
这就是常见的不正常结束vim产生的后果。解决方案依据不同的情况而不同。常见的处理方法为:
如果你之前的vim处理操作尚未保存,此时你应该要按下“R”,即使用(R)ecover的选项,此时vim会载入.man.config.swp的内容,让你自己来决定要不要保存。这样就能够救回来你之前未保存的工作。不过那个.man.config.swp并不会在你结束vim后自动删除,所以你离开vim后还得要自行删除.man.config.swp才能避免每次打开这个文件都会出现这样的警告。
如果你确定这个暂存文件是没有用的,那么你可以直接按下“D”删除掉这个暂存文件,即(D) elete it 这个选项即可。此时 vim 会载入 man.config,并且将旧的.man.config.swp 删除后,新建这次会使用的新的.man.config.swp。
至于这个发现暂存盘警告信息的界面中,有出现六个可用按钮,各按钮的说明如下:
[O]pen Read-Only:打开此文件成为只读文件,可以用在你只是想要查阅该文件内容并不想要进行编辑行为时。一般来说,在上课时,如果你是登录到同学的计算机去看他的配置文件,结果发现其实同学他自己也在编辑时,可以使用这个模式;
(E)dit anyway:还是用正常的方式打开你要编辑的那个文件,并不会载入暂存文件的内容。不过很容易出现两个用户互相改变对方的文件等问题。
(R)ecover:就是加载暂存文件的内容,用在你要救回之前未保存的工作。不过当你救回来并且保存离开vim后,还是要手动自行删除那个暂存文件。
(D)elete it:你确定那个暂存文件是无用的。那么打开文件前会先将这个暂存文件删除。这个操作其实是比较常做的。因为你可能不确定这个暂存文件是怎么来的,所以就删除掉它。
(Q)uit:按下q就离开vim,不会进行任何操作回到命令提示符。
(A)bort:忽略这个编辑行为,感觉上与quit非常类似。也会送你回到命令提示符就是。
10.3 vim 的功能
其实,目前大部分的distributions都以vim替代vi的功能了。如果你使用vi后,却看到界面的右下角有显示目前光标所在的行列号码,那么你的 vi 已经被 vim 所替代了,为什么要用 vim 呢?因为vim具有颜色显示的功能,并且还支持许多的程序语法(syntax),因此,当你使用vim编辑程序时(不论是 C 语言,还是 shell script),我们的 vim 将可帮你直接进行程序除错(debug)的功能。
如果你在文本模式下,输入alias时,出现这样的界面:
[root@www ~]# alias
….其他省略….
alias vi='vim' <==重点在这行啊。
这表示当你使用 vi 这个命令时,其实就是执行 vim。如果你没有这一行,那么你就必须要使用vimfilename来启动vim。基本上,vim的一般用法与vi完全一模一样。那么我们就来看看vim的界面是怎样的。假设我想要编辑/etc/man.config,则输入“vim /etc/man.config”。
图10-6 vim 的图示示意
图10-6是vim的示意图,在这个界面中有几点特色要说明:
1.由于man.config是系统规划的配置文件,因此vim会进行语法检验,所以你会看到界面中内部主要为深蓝色,且深蓝色那一行是以批注符号(#)为开头;
2.最下面一行的左边显示该文件的属性,包括141行与4617字符;
3.最下面一行的右边出现的1,1表示光标所在为第一行第一个字符位置之意(请看一下上图中的游标所在)。
所以,如果你向下移动到其他位置时,出现的非批注的数据就会如图10-7所示。
图10-7 非批注的数据
看到了吗?除了批注之外,其他的行就会有特别的颜色显示。可以避免你打错字。而且,最右下角的30%代表目前这个界面占整体文件的30%。
10.3.1 块选择(Visual Block)
刚才我们提到的简单的vi操作过程中,几乎提到的都是以行为单位的操作。那么如果我想要搞定的是一个块范围呢?举例来说,像下面这种格式的文件:
192.168.1.1 host1.class.net
192.168.1.2 host2.class.net
192.168.1.3 host3.class.net
192.168.1.4 host4.class.net
…..中间省略……
这个文件我将它放置到 http://linux.vbird.org/linux_basic/0310vi/hosts,你可以自行下载来看一看。假设我想要将 host1,host2 等复制起来,并且加到每一行的后面,也即每一行的结果要是“192.168.1.2 host2.class.net host2”这样的情况时,一般编辑器似乎不容易达到这个需求,但是咱们的 vim 是可以的。那就使用块选择(Visual Block)。当我们按下 v 或者 V 或者[Ctrl]+v 时,这个时候光标移动过的地方就会开始反白,这三个按键的意义如表10-2所示。
表10-2
下面来实际进行我们需要的操作。就是将host再加到每一行的最后面,你可以这样做:
1.使用 vim hosts 来打开该文件,记得该文件请由上述的链接下载先。
2.将光标移动到第一行的host那个h上头,然后按下[ctrl]-v,左下角出现块示意,如图10-8所示。
3.将光标移动到最底部,此时光标移动过的区域会反白,如图10-9所示。
图10-8 进入块功能的示意图
图10-9 块选择的结果示意图
4.此时你可以按下“y”来进行复制,当你按下y之后,反白的块就会消失不见。
5.最后,将光标移动到第一行的最右边,并且再用编辑模式向右按两个空格键,回到一般模式后,再按下“p”后,你会发现很有趣。如图10-10所示。
图10-10 将块的数据粘贴后的结果
通过上述的功能,你可以复制一个块,并且是贴在某个“块的范围”内,而不是以行为单位来处理你的整份文件。鸟哥个人是觉得这玩意儿非常有帮助,至少在进行排列整齐的文本文件中复制/删除块时,会是一个非常棒的功能。
10.3.2 多文件编辑
假设一个例子,你想要将刚才我们的hosts内的IP复制到你的/etc/hosts这个文件去,那么该如何编辑?我们知道在 vi 内可以使用:“r filename”来读入某个文件的内容,不过,这样毕竟是将整个文件读入。如果我只是想要部分内容呢?这个时候多文件同时编辑就很有用了。我们可以使用vim后面同时接好几个文件来同时打开。相关的按键如表10-3所示。
表10-3
在过去,鸟哥想要将A文件内的10条消息“移动”到B文件去,通常要开两个vim窗口来复制,偏偏每个vim都是独立的,因此并没有办法在A文件执行“nyy”再跑到B文件去执行“p”。在这种情况下最常用的方法就是通过鼠标圈选,复制后粘贴。不过这样一来还是有问题,因为鸟哥超级喜欢使用[Tab]按键进行编排对齐操作,通过鼠标却会将[Tab]转成空格键,这样内容就不一样了。此时这个多文件编辑就派上用场了。
现在你可以做一下练习。假设你要将刚才笔者提供的 hosts 内的前四行 IP 数据复制到你的/etc/hosts文件内,那可以怎么进行呢?可以这样:
1.通过“vim hosts /etc/hosts”命令来使用一个vim打开两个文件
2.在 vim 中先使用“:files”查看一下编辑的文件数据有什么,结果如图10-11 所示。至于图中最后一行显示的是“按下任意键”就会回到 vim 的一般模式。
图10-11 多文件编辑示意图
3.在第一行输入“4yy”复制四行。
4.在vim的环境下输入“n”会来到第二个编辑的文件,即/etc/hosts内。
5.在/etc/hosts下按“G”到最后一行,再输入“p”粘贴。
6.按下多次的“u”来还原原本的文件数据。
7.最终按下“:q”来离开vim的多文件编辑。
利用多文件编辑的功能,可以让你很快就将需要的数据复制到正确的文件内。当然这个功能也可以利用窗口界面来达到,那就是下面要提到的多窗口功能。
10.3.3 多窗口功能
在开始这个小节前,先来想象两个情况:
当我有一个文件非常大,我查阅到后面的数据时,想要对照前面的数据,是否需要使用[Ctrl]+f与[Ctrl]+b(或PageUp、PageDown功能键)来跑前跑后查阅?
我有两个需要对照着看的文件,不想使用前一小节提到的多文件编辑功能。
在一般窗口界面下的编辑软件大多有“切割窗口或者是冻结窗口”的功能来将一个文件切割成多个窗口的展现,那么vim能不能达到这个功能啊?可以。但是如何切割窗口并放入文件呢?很简单。在命令行模式输入“:sp{filename}”即可。那个filename可有可无,如果想要在新窗口启动另一个文件,就加入文件名,否则仅输入:sp时,出现的则是同一个文件在两个窗口间。
让我们来测试一下,你先使用“vim /etc/man.config”打开这个文件,然后用“1G”去到第一行,之后输入“:sp”再次打开这个文件一次,然后再输入“G”,结果会变成图10-12所示。
万一你再输入“:sp /etc/hosts”时,就会变成图 10-13 所示。
图10-12 窗口切割的示意图
图10-13 窗口切割的示意图
两个文件同时在一个屏幕上面显示,你还可以利用[Ctrl]+w+↑及[Ctrl]+w+↓在两个窗口之间移动呢。这样的话,复制、查阅等就变得很简单了。切割窗口的相关命令功能有很多,不过你只要记得这几个就好了,如表10-4所示。
表10-4
鸟哥第一次玩vim的切割窗口时,真是很高兴。竟然有这种功能,太棒了!
10.3.4 vim 环境设置与记录:~/.vimrc,~/.viminfo
有没有发现,如果我们以vim软件来查找一个文件内部的某个字符串时,这个字符串会被反白,而下次我们再次以vim编辑这个文件时,该查找的字符串反白情况还是存在呢。甚至于在编辑其他文件时,如果其他文件内也存在这个字符串,竟然还是主动反白。另外,当我们重复编辑同一个文件时,当第二次进入该文件时,光标竟然就在上次离开的那一行上面。
这是因为我们的vim会主动将你曾经做过的行为记录下来,好让你下次可以轻松作业。那个记录操作的文件就是:~/.viminfo。如果你曾经使用过vim,那你的主文件夹应该会存在这个文件才对。这个文件是自动产生的,你不必自行创建。而你在vim里头所做过的操作就可以在这个文件内部查询到。
此外,每个distributions对vim的默认环境都不太相同,举例来说,某些版本在查找到关键字时并不会高亮度反白,有些版本则会主动帮你进行缩排的行为。但这些其实都可以自行设置的,那就是vim 的环境设置。vim 的环境设置参数有很多,如果你想要知道目前的设置值,可以在一般模式时输入“:set all”来查阅,不过设置选项实在太多了,所以鸟哥在这里仅列出一些平时比较常用的一些简单的设置值,提供给你参考,如表10-5所示。
所谓的缩排,就是当您按下[Enter]编辑新的一行时,光标不会在行首,而是在与上一行的第一个非空格符处对齐。
表10-5
总之,这些设置值很有用处的。但是我是否每次使用vim都要重新设置一次各个参数值?其实我们可以通过配置文件来直接规定我们习惯的vim操作环境。整体vim的设置值一般是放置在/etc/vimrc这个文件中,不过,不建议你修改它。你可以修改~/.vimrc这个文件(默认不存在,请你自行手动创建),将你所希望的设置值写入。举例来说,可以是这样的一个文件:
[root@www ~]# vim ~/.vimrc
"这个文件的双引号 (") 是批注
set hlsearch "高亮度反白
set backspace=2 "可随时用退格键删除
set autoindent "自动缩排
set ruler "可显示最后一行的状态
set showmode "左下角那一行的状态
set nu "可以在每一行的最前面显示行号
set bg=dark "显示不同的底色色调
syntax on "进行语法检验,颜色显示
在这个文件中,使用“set hlsearch”或“ :set hlsearch”,即最前面有没有冒号“:”效果都是一样的。至于双引号则是批注符号,不要用错批注符号,否则每次使用vim时都会发生警告信息。创建好这个文件后,当你下次重新以vim编辑某个文件时,该文件的默认环境设置就是这么设置的。这样是否很方便你的操作?所以多利用vim的环境设置功能吧!
10.3.5 vim 常用命令示意图
为了方便大家查询在不同的模式下可以使用的vim命令,笔者查询了一些vim与Linux教育训练手册,发现图10-14非常值得大家参考,可以更快速有效地查询到需要的功能。
图10-14 vim 常用命令示意图
10.4 其他vim 使用注意事项
vim 其实不是那么好学,虽然它的功能确实非常强大。所以下面我们还有一些需要注意的地方要来跟大家分享。
10.4.1 中文编码的问题
很多朋友经常说他们的vim里面怎么无法显示正常的中文,其实这很有可能是因为编码的问题。因为中文编码有gb2312、big5与utf8等,如果你的文件是使用big5编码制作的,但在vim的终端界面中你使用的是统一码(utf8),由于编码的不同,你的文件内容当然就是一堆乱码了。怎么办?这时你得要考虑许多东西了。例如:
1.你的Linux系统默认支持的语系数据:这与/etc/sysconfig/i18n有关;
2.你的终端接口(bash)的语系:这与LANG这个变量有关;
3.你的文件原本的编码;
4.打开终端机的软件,例如在GNOME下面的窗口界面。
事实上最重要的是上面的第三与第四点,只要这两点的编码一致,你就能够正确看到与编辑你的中文文件,否则就会看到一堆乱码。
一般来说,中文编码使用big5时,在写入某些数据库系统中,在“许、盖、功”这些字体上面会发生错误。所以近期以来大多希望大家能够使用 utf8 来进行中文编码。但是在 Windows XP 上的软件经常默认使用big5的编码。此时就得要注意上述的这些情况。
在 Linux 本机前的 tty1~tty6 原本默认就不支持中文编码,所以不用考虑这个问题,因为你一定会看到乱码。现在笔者假设我们的文件文件内编码为big5时,而且我的环境是使用Linux的GNOME,启动的终端界面为GNOME-terminal软件,那笔者通常是这样来修正语系编码的行为:
root@www ~]# LANG=zh_CN.big5
然后在终端界面工具栏的“终端机”→“设置字符编码”→“中文(繁体)(BIG5)”选项点击一下,如果一切都没有问题了,再用vim去打开那个big5编码的文件,就没有问题了。
10.4.2 DOS 与Linux 的断行字符
我们在第7章里面谈到cat这个命令时,曾经提到过DOS与Linux断行字符的不同。而我们也可以利用 cat -A 来查看以 DOS(Windows 系统)建立的文件的特殊格式,也可以发现在 DOS 中使用的断行字符为^M$,我们称为CR与LF两个符号。而在Linux下面,则是仅有LF($)这个断行符号。这个断行符号对于Linux的影响很大,为什么呢?
我们说过,Linux下面的命令在开始执行时,它的判断依据是[Enter],而Linux的[Enter]为LF符号,不过,由于DOS的断行符号是CRLF,也就是多了一个^M的符号出来,在这样的情况下,如果是一个shellscript的程序文件,将可能造成“程序无法执行”的状态,因为它会误判程序所执行的命令内容。
那怎么办啊?很简单,将格式转换成为Linux即可。废话!这当然大家都知道,但是要以vi进入该文件,然后一个一个删除每一行的CR吗?当然没有这么没人性!我们可以通过简单的命令来进行格式的转换。
[root@www ~]# dos2UNIX [-kn] file [newfile]
[root@www ~]# UNIX2dos [-kn] file [newfile]
参数:
-k :保留该文件原本的 mtime 时间格式 (不更新文件上次内容经过修订的时间)
-n :保留原本的旧文件,将转换后的内容输出到新文件,如: dos2UNIX -n old new
范例一:将刚才上述练习的 /tmp/vitest/man.config 修改成为 dos 断行
[root@www ~]# cd /tmp/vitest
[root@www vitest]# cp -a /etc/man.config .
[root@www vitest]# ll man.config
-rw-r—r— 1 root root 4617 Jan 6 2007 man.config
[root@www vitest]# UNIX2dos -k man.config
UNIX2dos: converting file man.config to DOS format …
屏幕会显示上述的信息,说明断行转为 DOS 格式了。
[root@www vitest]# ll man.config
-rw-r—r— 1 root root 4758 Jan 6 2007 man.config
断行字符多了 ^M ,所以容量增加了。
范例二:将上述的 man.config 转成 man.config.linux 的 Linux 断行字符
[root@www vitest]# dos2UNIX -k -n man.config man.config.linux
dos2UNIX: converting file man.config to file man.config.linux in UNIX format …
[root@www vitest]# ll man.config*
-rw-r—r— 1 root root 4758 Jan 6 2007 man.config
-rw———- 1 root root 4617 Jan 6 2007 man.config.linux
因为断行字符以及DOS与Linux操作系统下面一些字符的定义不同,因此,不建议你在Windows系统当中将文件编辑好之后,才上传到Linux系统,会容易发生错误问题。而且,如果你在不同的系统之间复制一些纯文本文件时,千万记得要使用UNIX2dos或dos2UNIX来转换一下断行格式。
10.4.3 语系编码转换
很多朋友都会有的问题就是想要将语系编码进行转换。举例来说,想要将big5编码转成utf8。这个时候怎么办?难不成要每个文件打开会转存成utf8吗?不需要这样做。使用iconv这个命令即可。笔者将之前的vi章节做成big5编码的文件,你可以照下面的链接来下载先:
http://linux.vbird.org/linux_basic/0310vi/vi.big5
在终端机的环境下你可以使用“wget网址”来下载上述的文件。笔者将它下载在/tmp/vitest目录下。接下来让我们使用iconv这个命令来玩一玩编码转换。
[root@www ~]# iconv —list
[root@www ~]# iconv -f 原本编码 -t 新编码 filename [-o newfile]
参数:
—list :列出 iconv 支持的语系数据
-f :from ,后接原本的编码格式;
-t :to ,即后来的新编码要是什么格式;
-o file:如果要保留原本的文件,那么使用 -o 新文件名,可以建立新编码文件。
范例一:将 /tmp/vitest/vi.big5 转成 utf8 编码。
[root@www ~]# cd /tmp/vitest
[root@www vitest]# iconv -f big5 -t utf8 vi.big5 -o vi.utf8
[root@www vitest]# file vi*
vi.big5: ISO-8859 text, with CRLF line terminators
vi.utf8: UTF-8 Unicode text, with CRLF line terminators
有明显的不同吧?
这个命令支持的语系非常多,除了繁体中文的big5,utf8编码之外,也支持简体中文的gb2312,所以大家可以简单地将鸟站的网页数据下载后,利用这个命令来转成简体,就能够轻松读取文件数据。不过不要将转成简体的文件又上传成为你自己的网页,这明明是鸟哥写的不是吗?
不过如果是要将繁体中文的utf8转成简体中文的utf8编码时,那就得费些功夫了。举例来说,如果要将刚才那个vi.utf8转成简体的utf8时,可以这样做:
[root@www vitest]# iconv -f utf8 -t big5 vi.utf8 | \
> iconv -f big5 -t gb2312 | iconv -f gb2312 -t utf8 -o vi.gb.utf8
10.5 重点回顾
Linux下面的配置文件多为文本文件,故使用vim即可进行设置编辑。
vim 可视为程序编辑器,可用以编辑 shell script、配置文件等,避免打错字。
vi 为所有 UNIX like 的操作系统都会存在的编辑器,且执行速度快。
vi有三种模式,一般模式可变换到编辑与命令行模式,但编辑模式与命令行模式不能互换。
常用的按键有i,[Esc],:wq等。
vi的界面大致可分为两部分:上半部的本文与最后一行的状态+命令行模式。
数字是有意义的,用来说明重复进行几次操作的意思,如5yy为复制5行的意思。
光标的移动中,大写的G经常使用,尤其是1G、G,表示移动到文章的头、尾功能。
vi的替换功能也很棒。:n1,n2s/old/new/g要特别注意学习起来。
小数点“.”为重复进行前一次操作,也是经常使用的按键功能。
进入编辑模式几乎只要记住i,o,R三个按钮即可,尤其是新增一行的o与替代的R。
vim会主动创建swap暂存文件,所以不要随意断线。
可以使用[ctrl]-v进行复制/粘贴/删除的行为。
使用:sp功能可以切割窗口。
vim的环境设置可以写入~/.vimrc文件中。
可以使用iconv进行文件语系编码的转换。
使用dos2UNIX及UNIX2dos可以变更文件每一行的行尾断行字符。
10.6 本章练习
实作题部分
在第8章的情境模拟题二的第五点,编写/etc/fstab时,当时使用nano这个命令,请尝试使用vim去编辑/etc/fstab,并且将第8章新增的那一行的defatuls改成default,会出现什么状态?离开前请务必要修订成原本正确的信息。此外,如果将该行批注(最前面加#),你会发现字体颜色也有变化。
尝试在你的系统中,你惯常使用的那个账号的目录下,将本章介绍的vimrc内容进行一些常用设置,包括:
设置查找高亮度反白;
设置语法检验启动;
设置默认启动行号显示;
设置有两行状态栏(一行状态+一行命令行):set laststatus=2。
简答题部分
我用vi打开某个文件后,要在第34行向右移动15个字符,应该在一般模式中执行什么命令?
在vi打开的文件中,如何去到该文件的页首或页尾?
在vi打开的文件中,如何在光标所在行中移动到行头及行尾?
vi的一般模式情况下,按下“r”有什么功能?
在vi的环境中,如何将目前正在编辑的文件另存新文件名为newfilename?
在linux下面最常使用的文本编辑器为vi,请问如何进入编辑模式?
在vi软件中,如何由编辑模式跳回一般模式?
在vi环境中,若上下左右键无法使用时,请问如何在一般模式移动光标?
在vi的一般模式中,如何删除一行、n行;如何删除一个字符?
在vi的一般模式中,如何复制一行、n行并加以粘贴?
在vi的一般模式中如何查找string这个字符串?
在vi的一般模式中,如何替换word1成为word2,而若需要使用确认机制,又该如何?
在vi目前的编辑文件中,在一般模式下,如何读取一个文件filename进入当前文件?
在vi的一般模式中,如何存盘、离开、存盘后离开、强制存盘后离开?
在vi下面做了很多的编辑操作之后,却想还原成原来的文件内容,应该怎么进行?
我在vi这个程序当中,不想离开vi,但是想执行ls/home这个命令,vi有什么额外的功能可以达到这个目的?
10.7 参考数据与扩展阅读
维基百科:ASCII的代码与图示对应表:http://zh.wikipedia.org/wiki/ASCII
关于vim是什么的说明(繁体):http://www.vim.org/6k/features.zh.txt。
李果正兄的大家来学vim:http://info.sayya.org/~edt1023/vim/
麦克星球 Linux Fedora 心得笔记:
繁体/简体中文的转换方法:http://blog.xuite.net/michaelr/linux/15650102