vi编辑器的学习使用(二十五)
虽然Vim编辑器在可视的情况下可以极好的完成我们的工作,但是有时我们是也需要使用命令行命令的.例如在脚本中命令行命令的使用会更容易,同时有许多特别的命令是只在命令模式下才可以实现的.
:delete命令可以删除一个范围内的文本行.例如我们要删除1到5行,我们可以用下面的命令来做:
:1,5 delete
:delete命令的一般格式如下:
:range delete register count
在这个命令中的register是我们的删除的文本要放入的寄存器.这个可以是我们用a-z命名的寄存器中的一个.如果我们使用大写的字符做为寄存器的名字,那么这些文本就会被添加到已经存在文本的寄存器中.如果没有指定这个参数,那么就会使用未命名的寄存器.而count则指出要删除的行数.range则是指明要使用的行.
我们还可以使用命令来删除含有指定字符串的行.如我们可以用下面的命令来删除从第一个包含字符串hello到第一个包含字符串goodbye的行之间所有的行:
:/hello/,/goodbye/ delete
在这里我们要注意的就是如果goodbye在hello之前出现,那么这个命令就不会正常的工作了.我们还可以使用偏移量(offset)来重新定义要查找的字符串.例如/hello/+1是指含有hello字符串行的下一行,因而我们还可以使用下面的命令来进行删除的操作:
:/beach/+1,/seashore/-1 delete
我们还可以使用下面的一些简写的运算符:
// 向前查找上一次使用的模式
/? 向后查找上一次使用的模式
/& 向前查找上一次使用的子模式
(注:这个地方不懂,也不晓如何来用)
我们还可以使用链式的模式,例如下面的命令在找到字符串first以后要查找second字符串:
/first//second
所以我们还可以使用下面这样的删除命令:
:/hello//goodbye/ delete
我们还可以指定行号,用来指明在第几行进行查找,如果我们要从第七行开始查找,我们可以使用下面的命令:
7/first/
如果我们只是执行一个:命令,那么Vim编辑器就会进行命令行模式然后允许我们指定一个要删除的范围.如果我们在这个命令之前指定了一个数字,例如5:,那么要删除的范围就是这个数字所指定的范围(包括当前行).事实上这样指定的范围如下:
:...+count-1
例如我们在一段文本中执行下面的命令:
3:delete
这实际上是执行下面的命令:
:...+2 delete
这个命令可以删除当前行以及当前行以下的两行,总计三行的文本.
删除命令的另一个形式如下:
:line delete count
在这种情况下,:delete命令回到line所指定的行(默认为当前行),然后删除count行文本(包括当前行).
:copy命令是将几行的文本从一个地方复制到另一个地方.这个命令的一般格式如下:
:range copy address
如果没有特别指定,range默认是指当前行.这个命令是拷贝range所指定的范围行的文本到address指定行的后面.
与:copy命令相类似的是:move命令,所不同的只是这个命令是移动而不复制.
假如我们要在我们正编辑的文本中插入一些行,而由于某些原因,我们要使用命令行的方式来完成这样的工作.这时我们就要将光标移动我们希望新行出现的上一行.换句话说,我们是希望将插入的文本出现在当前行的后面.然后我们可以执行命令:append来开始我们的插入过程,我们输入我们要插入的内容并用句号(.)来结束一行的输入.例如我们在一个测试文本中执行下面的命令:
:1append
这个命令是要第一行的后面插入我们新的文本行.执行这个命令后,我们可以在Vi的底部输入我们要插入的内容.当我们要结束我们的输入时,只要在一新行输入.就可以了.这样我们输入的内容就会出在第一行的后面了.
:append命令的一般格式如下:
:line append
我们输入的新文本将会插入在line所指定的行后面.
:insert命令也可以插入文本,这个命令的一般形式如下:
:line insert
这个命令与:append命令相似,所不同的是后者是当前行的后面插入文本,而前者是在当前的前面插入文本.
我们不必打开number选项也可以实现在打印一行文本时打印此行的行号.命令:#与:print命令相类似,所不同的只是前者可以打印出行号.
例如在我们的测试文本中执行下面的命令:
:1 print
执行结果如下:
A UNIX sales lady,Lenore,
而我们执行下面的命令:
:1#
执行结果如下:
1 A UNIX sales lady,Lenore,
选项list可以使得不可见的字符成为可见字符.命令:list可以列出指定的行,而且这个命令全认为list选项已经打开.如下面的命令:
:1,5 list
这个命令就可以列出1-5行的内容.
这个命令与:print命令不同的地方只是这个命令也可以打印出回车,Tab等不可见的字符.
:z命令可以打印出一个范围内的文本行(默认情况下为当前行)以及这一行附近的行.例如我们执行下面的命令:
:100 z
这个命令会打印出从第100行开始的直到当前屏幕满屏的所有的文本行.
这个命令可以指定一个数字,用来表示除了打印指定的行以外要额外打印的行.例如下面的命令:
:100 z 3
这个就使得Vim除了打印第100行还要另打印额外的三行.
:z命令以后还可以再跟上一个代码用来表示要显示多少的文本.可用的代码如下:
代码 起始行 结束行 当前行
+ 当前行 向前一个屏幕 向前一个屏幕的下一行
- 向后一个屏幕 当前行 当前行
^ 向后两个屏幕 向后一个屏幕 向后一个屏幕
. 向后半屏 向前半屏 向前半屏
= 向后半屏 向前半屏 当前行
基本的substitute命令格式如下:
:range substitute /from/to/flags count
这里的定义符可以是除了字母,数字,反斜线,双引号或是竖线以外的任何字符.在Vim编辑器中Vim还使用一些特殊的字符来表示特殊的事物.例如*表示重复0次或是多次.如果我们设置了nomagic选项,那么这些字符的特殊意义就会被关掉了.
命令:smgic可以执行一个替换操作,但是这个命令要求我们设置了magic选项.
例如我们可以使用只有一行的文件来测试这些命令.我们可以用命令将整个文件打印出来:
:%print
Test aaa* aa* a*
然后我们设置了magic选项并且执行替换命令 .p标记告诉编辑器打印出他所改变的行:
:set magic
:1 substitute /a*/b/p
命令的执行结果如下:
bTest aaa* aa* a*
这个命令只是改变了一行开始的部分.为什么会将Test变为b*Test而且并没有a呢?这就是因为*可以匹配0次或是多次,而Test正是以0个a开始的.但是为什么只是替换了一次呢?这是因为:substitute命令中是改变第一个出现的地方.如果我们使用g标记就可以替换全部的匹配项了,我们撤销刚才的命令并执行下面的命令:
:undo
:1 substitute /a*/b/pg
这个命令的执行结果如下:
bTest b*b b*b b*
现在我们在关闭magic选项的情况下再做一次:
:undo
:set nomagic
:1 substitute /a*/b/pg
这个命令的执行结果如下:
Test aab ab b
在没有设置magic的情况下,*仅是一个*.
而:smagic命令则是在执行替换命令时强制转换*以及其他一些字符的意义,例如我们执行下面的命令:
:undo
:smagic /a*/b/pg
这个命令的执行结果如下:
bTest b*b b*b b*
而相类似的是命令:snomagic选项强行关掉magic选项:
:undo
:snomagic /a*/b/pg
这个命令的执行结果如下:
Test aab ab b
&命令可以重复执行替换.这个命令可以保存旧的from和to的字符串,但是允许我们使用不同的范围(range)和标记(flags).这个命令的一般形式如下:
:range & flags count
例如我们执行下面的命令:
:1 substitute /a/+/b/p
这个命令的执行结果如下:
Test b* aa* a*
这个命令可以改变第一个出现from所指的字符的地方.但是我们希望是的整个一行都要发生相应的替换,这时我们可以重复这一次替换命令:
:&g
这一次在命令的执行过程中就不会打印执行结果,因为我们在这里指定的标记是g,而不是p.这个命令的执行结果如下:
Test b* b* b*
命令:&和命令:substitute在没有指定替换字符串的情况下作用相同,都可以执行上一次的替换命令.
在正常的命令状态下命令&可以重复上一次的:substitute命令.例如如果我们执行下面的命令就会将第五行中的字符manager变为idiot:
:5 substitute /manager/idiot/
这时如果在正常的命令模式下我们执行命令&,那么这一行中的下一个manager字符串也会发生变化.如果我们下移一行然后执行命令&,那么这一行也会发生相应的变化.如果我们在这个命令中指定了count,那么这个命令就可以作用多行.
:~命令与命令&g相类似,所不同的是前者使用的字符是上一次使用/或是?查找时使用的字符串,而不是上一次:substitute命令中的字符串.这个命令的一般格式如下:
:range~ flags count
在一般的情况下,:substitute命令只是改变一行中第一个出现指定的字符串处,除非我们使用了g标记.如果我们希望g标记能成为默认的设置,我们可以使用下面的命令:
:set gdefault
但是这里我们要注意的就是也许这样的设置会打断我们的一些脚本.
到了现在我们所说过的一些命令都是有一个限制的,那就是我们所要执行的命令只作用在相邻的行上.然而有时我们所希望是改变含有特定类型的行,这时我们就要用到:global命令了.这个命令的一般形式如下:
:range global /pattern/command
这个命令可以告诉Vim编辑器对在指定的范围内包含有指定的类型的所有行执地指定的命令.例如如果我们要打印出一个文件中所有包含单词Professor的行,我们可以使用下面的命令:
:%global /Professor/ print
而命令:global!将对所有的行执行指定的命令,但是却不匹配指定的类型.与其相类似的是:vglobal命令.
命令:ijump查找指定的类型,并且会跳转到指定的范围内第一个出现的单词处.这个命令不仅会在当前文件中进行查找,而且会在由#include所包含进来的文件中进行查找.这个命令的一般格式如下:
:range ijump count [/]pattern[/]
如果我们在这个命令中指定了count,那么就会跳转到第count个类型出现处.这个类型会被看作是精确的文本,除非是由斜线括起来的.
例如下面的一个Hello.c的文件:
#include <stdio.h>
int main()
{
printf("Hello World/n");
return (0);
}
如果我们执行下面的命令就会跳转到第一个含有 define EOF的行处:
:ijump /define/s*EOF/
在我们目录的情况,他是在包含进来的文件stdio.h中
与这个命令相类似的是命令:ilist,所不同的只是这个命令是列出相应的行而不是跳转到相应的行.
命令:isearch与:ilist命令相类似,只是这个命令列出第一个出现指定内容的行.
最后命令:isplit是命令:ijump和命令:split的组合.
我们已经知道用命令[CTRL-D来跳转到当前光标下的宏定义处.下面的命令也可以起到同样的作用:
:djump name
例如我们要跳转到宏MAX处,我们可以用下面的命令:
:djump MAX
执行这个命令我们并不必需要知道我们定义的宏的全名,如果我们只是知道宏名的一部分,我们就可以使用由斜线括起来的常规表达式来进行相应的查找.如下面的命令:
:djump /MAX/
我们还可以指定参数来控制这个命令的查找范围,如下面的命令:
:50,100 djump /MAX/
这个命令只在第50到第100行内进行相应的查找.
如果我们希望查找到是第二个而不是第一个宏定义,我们可以通过指定count参数来做到.例如我们要查找第二个MAX的定义处,我们可以用下面的命令:
:djump 2 MAX
下面的命令会在一个新窗口内显示宏定义:
:range dsplit count [/]pattern[/]
这个命令是命令:split和命令:djump的组合.
命令:dlist与命令:dsplit相类似,只是前者并不会移动到一个宏的定义处,而是列出匹配的宏定义.
而命令:dsearch只是显示第一个匹配的宏定义.如果命令:ilist,ijump,:djump,:dlist,:dsearch带上!选项,那么在注释内的定义也可以进行查找.
如果我们要改变当前Vim的工作目录,我们可以用下面的命令:
:cd dir
这个命令与系统的cd命令相类似.如果没有指定目录,那么就会回到我们的用户主目录.
要查看当前Vim的工作在哪一个目录下,我们可以有用下面的命令:
:pwd
要回到前一个工作目录,我们可以用下面的命令:
:cd -
下面的命令可以打印出当前文件的名字以及一些相关的行信息:
:file
如果我们要改变当前文件的名字,我们可以使用下面的命令:
:file name
例如我们正在编辑的文件名为complete.txt,我们可以使用:write命令进行保存.现在我们要缩短文件并且存为summary.txt,我们可以执行下面的命令:
:file summary.txt
如果我们继续进行编辑,那么所的改动都会被存入文件summary.txt中.
与:file命令相似,命令:=可以打印出当前行的行号.
:write命令可以将缓冲区或是一个文件中指定范围内的文本存入.他还有一些其他的选项.例如下面的命令就可以将我们正编辑的文件内容追加到文件collect.txt中:
:write >> collect.txt
如果这个文件并不存在,那么这个命令就会给出错误信息.如果我们要强行追加,可以使用!选项:
:write!>>collect.txt
:write命令不仅可以保存文件,而且可以将文件导入其他的程序.在Linux系统中,我们可以用下面的命令将文件发送到打印机:
:write !lpr
(注::write! lpr与:write !lpr这两个命令的不同,前才是强行保存文件而后者则是将文件发送到打印机)
命令:uddate与命令:write相类似,所不同的只是如果缓冲区没有被修改,那么这个命令就不会起作用了.
:read命令将会读入一个文件.这个命令的一般格式如下:
:line read file
这个命令会将名为file的文件读入并且插入在line后面.如果没有指定文件,那么就会使用当前的文件,如果没有指定要插入的行,那么就会使用当前的行.
与:write命令相类似,:read命令可以使用一个命令而不是一个文件.如果要读入一个命令的输出并插入到当前行的后面,我们可以使用下面的命令:
:line read !command
我们在以前的学习曾学过如何在寄存器中录制宏.如果我们要在命令行中使用这些宏,我们可以用下面的命令来执行寄存器中的宏内容:
:line@register
这个命令会将光标移动到指定的行,然后执行寄存器中的内容.这就意味着下面的命令执行上一次的命令行:
:@:
如果要执行上一次的:@register命令,我们可以用下面的命令:
:line@@
命令:>使得文本右缩进,:<命令使文本向左缩进.例如下面的命令将会使第五行到第十行向右缩进:
:5,10>
:change命令与:delete命令相类似,所不同的只是他还同时执行:insert命令,也就是有我们可以同时输入我们要插入的文本.
命令:startinsert命令可以开始插入模式,就像是我们在正常模式下执行i命令一样.
如果我们要将几行合并为一行,我们可以使用命令:join,在这个命令的执行中将会使用空格来分隔这几行.如果我们不希望加入空格,我们可以用下面的命令来合并:
:join!
下面的命令可以将指定的行的文本复制到寄存器中:
:range yank register
如果没有指定寄存器,将会使用未命名寄存器.
:put命令会将寄存中的内容粘贴到指定的文本行的后面.例如要将寄存器中的内容粘贴到第五行的后面,我们可以用下面的命令:
:5put a
如果要将文本放在这一行的前面,我们可以用下面的命令:
:5put! a
:undo命令会撤销上一次的命令操作,与u命令相类似.而:redo命令会重做撤销的操作,与命令CTRL-R命令相类似.
如果要标记一行的开始,可以用下面的命令:
:mark {register}
如果指定了行,那么那一行将会被标记.命令:k将会起到同样的作用,只是我们不需要在寄存器名前加上一个空格.例如下面的命令:
:100 mark x
:100 ka
命令:preserve可以将整个文件写入swap文件.这就使得我们可以在没有原始文件的情况下来修复我们的编辑部分.
如果我们要执行单一的Shell命令,我们可以用下面的命令:
:!cmd
cmd就是我们要执行的系统命令.
例如要查看当前的日期,我们可以用下面的命令:
:!date
如果我们要重复上一次的Shell命令,我们可以用下面的命令来做:
:!!
最后下面的命令可以挂起Vim而进入命令提示行:
:shell
现在我们就可以执行各种的系统的命令了.在我们完成我们的工作以后,我们可以用exit命令回到Vim编辑器.
下面的一些选项可以控制命令的执行:
shell 我们要执行的命令名
shellcmdflag 跟在命令后的标记
shellquote 在命令中的引用字符
shellxquote 命令中的引用字符和重定向
shellpipe 使用管道的字符串
shellredir 重定向输出的字符串
shellslash 在文件名中使用向前的斜线(只在DOS中使用)
命令:history可以当前命令模式下的命令历史
Vim编辑器可以记录各种命令的历史,下面的标记指出所记录的历史类型;
c cmd : 命令行历史
s search / 查找字符串历史
e expr = 表达式寄存器历史
i input @ 输入行历史
a all 所有的历史
如果我们列出所有的历史,我们可以用下面的命令:
:history all
:history命令的一般格式如下:
:history code first,last
如果没有指定first和last,那么就会列出所有的命令.first参数默认是指历史第一个输入的,而last就是指最后一个.负数是指由历史的结束处向前的数的第几个.例如-2是指最后个命令的输入.
例如下面的命令列出第一个到第五个的命令行历史:
:history c 1,5
而下面的命令则是列出了上五次的查找历史:
:history s -5
history选项可以用来控制记录的历史命令数.例如我们要将记录的历史命令数增加为50,我们可以用下面的命令:
:set history=50
Vim编辑器可以记录上几次的错误以及在屏幕最后一行显示的信息.要查看这些信息,我们可以用下面的命令:
:messages
下面的命令可以使得信息的输出在显示在屏幕的同时会拷贝到一个文件中:
:redir > file
如果要停止拷贝,可以使用下面的命令:
:redir END
这个命令在保存调试信息时会显得更为有用.
我们还可以用:redir命令将输出追加到文件中:
:redir >> file
:normal命令可以使我们执行一个正常模式下的命令.例如下面的命令是将光标下的单词改为DONE:
:normal cwDONE
在行这些命令时要求命令必须是一个完整的命令.如果我们已经挂起Vim然后执行命令时,Vim显示全直到命令完全时也会发生变化.
下面的命令会将当前的文本写入文件,然后退出:
:exit
如果我们使用!选项,即时这个文件被标记为只读,那么Vim也会强行保存.
我们还可以在命令行指定一个文件名,那么当前的内容就会在退出以前写入我们所指定的文件,例如下面的命令:
:exit save.txt
如果我们只是想着将文件中的一部分保存到另一个文件,我们可以指定一个范围来保存.例如要保存100行,我们可以用下面的命令:
:1,100 exit save.txt
下面的命令与:exit命令相类似,不同的是这个命令总是会保存文件:
:range wq! file
而:exit命令只是在文件发生改变时才会保存.
:delete命令可以删除一个范围内的文本行.例如我们要删除1到5行,我们可以用下面的命令来做:
:1,5 delete
:delete命令的一般格式如下:
:range delete register count
在这个命令中的register是我们的删除的文本要放入的寄存器.这个可以是我们用a-z命名的寄存器中的一个.如果我们使用大写的字符做为寄存器的名字,那么这些文本就会被添加到已经存在文本的寄存器中.如果没有指定这个参数,那么就会使用未命名的寄存器.而count则指出要删除的行数.range则是指明要使用的行.
我们还可以使用命令来删除含有指定字符串的行.如我们可以用下面的命令来删除从第一个包含字符串hello到第一个包含字符串goodbye的行之间所有的行:
:/hello/,/goodbye/ delete
在这里我们要注意的就是如果goodbye在hello之前出现,那么这个命令就不会正常的工作了.我们还可以使用偏移量(offset)来重新定义要查找的字符串.例如/hello/+1是指含有hello字符串行的下一行,因而我们还可以使用下面的命令来进行删除的操作:
:/beach/+1,/seashore/-1 delete
我们还可以使用下面的一些简写的运算符:
// 向前查找上一次使用的模式
/? 向后查找上一次使用的模式
/& 向前查找上一次使用的子模式
(注:这个地方不懂,也不晓如何来用)
我们还可以使用链式的模式,例如下面的命令在找到字符串first以后要查找second字符串:
/first//second
所以我们还可以使用下面这样的删除命令:
:/hello//goodbye/ delete
我们还可以指定行号,用来指明在第几行进行查找,如果我们要从第七行开始查找,我们可以使用下面的命令:
7/first/
如果我们只是执行一个:命令,那么Vim编辑器就会进行命令行模式然后允许我们指定一个要删除的范围.如果我们在这个命令之前指定了一个数字,例如5:,那么要删除的范围就是这个数字所指定的范围(包括当前行).事实上这样指定的范围如下:
:...+count-1
例如我们在一段文本中执行下面的命令:
3:delete
这实际上是执行下面的命令:
:...+2 delete
这个命令可以删除当前行以及当前行以下的两行,总计三行的文本.
删除命令的另一个形式如下:
:line delete count
在这种情况下,:delete命令回到line所指定的行(默认为当前行),然后删除count行文本(包括当前行).
:copy命令是将几行的文本从一个地方复制到另一个地方.这个命令的一般格式如下:
:range copy address
如果没有特别指定,range默认是指当前行.这个命令是拷贝range所指定的范围行的文本到address指定行的后面.
与:copy命令相类似的是:move命令,所不同的只是这个命令是移动而不复制.
假如我们要在我们正编辑的文本中插入一些行,而由于某些原因,我们要使用命令行的方式来完成这样的工作.这时我们就要将光标移动我们希望新行出现的上一行.换句话说,我们是希望将插入的文本出现在当前行的后面.然后我们可以执行命令:append来开始我们的插入过程,我们输入我们要插入的内容并用句号(.)来结束一行的输入.例如我们在一个测试文本中执行下面的命令:
:1append
这个命令是要第一行的后面插入我们新的文本行.执行这个命令后,我们可以在Vi的底部输入我们要插入的内容.当我们要结束我们的输入时,只要在一新行输入.就可以了.这样我们输入的内容就会出在第一行的后面了.
:append命令的一般格式如下:
:line append
我们输入的新文本将会插入在line所指定的行后面.
:insert命令也可以插入文本,这个命令的一般形式如下:
:line insert
这个命令与:append命令相似,所不同的是后者是当前行的后面插入文本,而前者是在当前的前面插入文本.
我们不必打开number选项也可以实现在打印一行文本时打印此行的行号.命令:#与:print命令相类似,所不同的只是前者可以打印出行号.
例如在我们的测试文本中执行下面的命令:
:1 print
执行结果如下:
A UNIX sales lady,Lenore,
而我们执行下面的命令:
:1#
执行结果如下:
1 A UNIX sales lady,Lenore,
选项list可以使得不可见的字符成为可见字符.命令:list可以列出指定的行,而且这个命令全认为list选项已经打开.如下面的命令:
:1,5 list
这个命令就可以列出1-5行的内容.
这个命令与:print命令不同的地方只是这个命令也可以打印出回车,Tab等不可见的字符.
:z命令可以打印出一个范围内的文本行(默认情况下为当前行)以及这一行附近的行.例如我们执行下面的命令:
:100 z
这个命令会打印出从第100行开始的直到当前屏幕满屏的所有的文本行.
这个命令可以指定一个数字,用来表示除了打印指定的行以外要额外打印的行.例如下面的命令:
:100 z 3
这个就使得Vim除了打印第100行还要另打印额外的三行.
:z命令以后还可以再跟上一个代码用来表示要显示多少的文本.可用的代码如下:
代码 起始行 结束行 当前行
+ 当前行 向前一个屏幕 向前一个屏幕的下一行
- 向后一个屏幕 当前行 当前行
^ 向后两个屏幕 向后一个屏幕 向后一个屏幕
. 向后半屏 向前半屏 向前半屏
= 向后半屏 向前半屏 当前行
基本的substitute命令格式如下:
:range substitute /from/to/flags count
这里的定义符可以是除了字母,数字,反斜线,双引号或是竖线以外的任何字符.在Vim编辑器中Vim还使用一些特殊的字符来表示特殊的事物.例如*表示重复0次或是多次.如果我们设置了nomagic选项,那么这些字符的特殊意义就会被关掉了.
命令:smgic可以执行一个替换操作,但是这个命令要求我们设置了magic选项.
例如我们可以使用只有一行的文件来测试这些命令.我们可以用命令将整个文件打印出来:
Test aaa* aa* a*
然后我们设置了magic选项并且执行替换命令 .p标记告诉编辑器打印出他所改变的行:
:set magic
:1 substitute /a*/b/p
命令的执行结果如下:
bTest aaa* aa* a*
这个命令只是改变了一行开始的部分.为什么会将Test变为b*Test而且并没有a呢?这就是因为*可以匹配0次或是多次,而Test正是以0个a开始的.但是为什么只是替换了一次呢?这是因为:substitute命令中是改变第一个出现的地方.如果我们使用g标记就可以替换全部的匹配项了,我们撤销刚才的命令并执行下面的命令:
:undo
:1 substitute /a*/b/pg
这个命令的执行结果如下:
bTest b*b b*b b*
现在我们在关闭magic选项的情况下再做一次:
:undo
:set nomagic
:1 substitute /a*/b/pg
这个命令的执行结果如下:
Test aab ab b
在没有设置magic的情况下,*仅是一个*.
而:smagic命令则是在执行替换命令时强制转换*以及其他一些字符的意义,例如我们执行下面的命令:
:undo
:smagic /a*/b/pg
这个命令的执行结果如下:
bTest b*b b*b b*
而相类似的是命令:snomagic选项强行关掉magic选项:
:undo
:snomagic /a*/b/pg
这个命令的执行结果如下:
Test aab ab b
&命令可以重复执行替换.这个命令可以保存旧的from和to的字符串,但是允许我们使用不同的范围(range)和标记(flags).这个命令的一般形式如下:
:range & flags count
例如我们执行下面的命令:
:1 substitute /a/+/b/p
这个命令的执行结果如下:
Test b* aa* a*
这个命令可以改变第一个出现from所指的字符的地方.但是我们希望是的整个一行都要发生相应的替换,这时我们可以重复这一次替换命令:
:&g
这一次在命令的执行过程中就不会打印执行结果,因为我们在这里指定的标记是g,而不是p.这个命令的执行结果如下:
Test b* b* b*
命令:&和命令:substitute在没有指定替换字符串的情况下作用相同,都可以执行上一次的替换命令.
在正常的命令状态下命令&可以重复上一次的:substitute命令.例如如果我们执行下面的命令就会将第五行中的字符manager变为idiot:
:5 substitute /manager/idiot/
这时如果在正常的命令模式下我们执行命令&,那么这一行中的下一个manager字符串也会发生变化.如果我们下移一行然后执行命令&,那么这一行也会发生相应的变化.如果我们在这个命令中指定了count,那么这个命令就可以作用多行.
:~命令与命令&g相类似,所不同的是前者使用的字符是上一次使用/或是?查找时使用的字符串,而不是上一次:substitute命令中的字符串.这个命令的一般格式如下:
:range~ flags count
在一般的情况下,:substitute命令只是改变一行中第一个出现指定的字符串处,除非我们使用了g标记.如果我们希望g标记能成为默认的设置,我们可以使用下面的命令:
:set gdefault
但是这里我们要注意的就是也许这样的设置会打断我们的一些脚本.
到了现在我们所说过的一些命令都是有一个限制的,那就是我们所要执行的命令只作用在相邻的行上.然而有时我们所希望是改变含有特定类型的行,这时我们就要用到:global命令了.这个命令的一般形式如下:
:range global /pattern/command
这个命令可以告诉Vim编辑器对在指定的范围内包含有指定的类型的所有行执地指定的命令.例如如果我们要打印出一个文件中所有包含单词Professor的行,我们可以使用下面的命令:
:%global /Professor/ print
而命令:global!将对所有的行执行指定的命令,但是却不匹配指定的类型.与其相类似的是:vglobal命令.
命令:ijump查找指定的类型,并且会跳转到指定的范围内第一个出现的单词处.这个命令不仅会在当前文件中进行查找,而且会在由#include所包含进来的文件中进行查找.这个命令的一般格式如下:
:range ijump count [/]pattern[/]
如果我们在这个命令中指定了count,那么就会跳转到第count个类型出现处.这个类型会被看作是精确的文本,除非是由斜线括起来的.
例如下面的一个Hello.c的文件:
#include <stdio.h>
int main()
{
printf("Hello World/n");
return (0);
}
如果我们执行下面的命令就会跳转到第一个含有 define EOF的行处:
:ijump /define/s*EOF/
在我们目录的情况,他是在包含进来的文件stdio.h中
与这个命令相类似的是命令:ilist,所不同的只是这个命令是列出相应的行而不是跳转到相应的行.
命令:isearch与:ilist命令相类似,只是这个命令列出第一个出现指定内容的行.
最后命令:isplit是命令:ijump和命令:split的组合.
我们已经知道用命令[CTRL-D来跳转到当前光标下的宏定义处.下面的命令也可以起到同样的作用:
:djump name
例如我们要跳转到宏MAX处,我们可以用下面的命令:
:djump MAX
执行这个命令我们并不必需要知道我们定义的宏的全名,如果我们只是知道宏名的一部分,我们就可以使用由斜线括起来的常规表达式来进行相应的查找.如下面的命令:
:djump /MAX/
我们还可以指定参数来控制这个命令的查找范围,如下面的命令:
:50,100 djump /MAX/
这个命令只在第50到第100行内进行相应的查找.
如果我们希望查找到是第二个而不是第一个宏定义,我们可以通过指定count参数来做到.例如我们要查找第二个MAX的定义处,我们可以用下面的命令:
:djump 2 MAX
下面的命令会在一个新窗口内显示宏定义:
:range dsplit count [/]pattern[/]
这个命令是命令:split和命令:djump的组合.
命令:dlist与命令:dsplit相类似,只是前者并不会移动到一个宏的定义处,而是列出匹配的宏定义.
而命令:dsearch只是显示第一个匹配的宏定义.如果命令:ilist,ijump,:djump,:dlist,:dsearch带上!选项,那么在注释内的定义也可以进行查找.
如果我们要改变当前Vim的工作目录,我们可以用下面的命令:
:cd dir
这个命令与系统的cd命令相类似.如果没有指定目录,那么就会回到我们的用户主目录.
要查看当前Vim的工作在哪一个目录下,我们可以有用下面的命令:
:pwd
要回到前一个工作目录,我们可以用下面的命令:
:cd -
下面的命令可以打印出当前文件的名字以及一些相关的行信息:
:file
如果我们要改变当前文件的名字,我们可以使用下面的命令:
:file name
例如我们正在编辑的文件名为complete.txt,我们可以使用:write命令进行保存.现在我们要缩短文件并且存为summary.txt,我们可以执行下面的命令:
:file summary.txt
如果我们继续进行编辑,那么所的改动都会被存入文件summary.txt中.
与:file命令相似,命令:=可以打印出当前行的行号.
:write命令可以将缓冲区或是一个文件中指定范围内的文本存入.他还有一些其他的选项.例如下面的命令就可以将我们正编辑的文件内容追加到文件collect.txt中:
:write >> collect.txt
如果这个文件并不存在,那么这个命令就会给出错误信息.如果我们要强行追加,可以使用!选项:
:write!>>collect.txt
:write命令不仅可以保存文件,而且可以将文件导入其他的程序.在Linux系统中,我们可以用下面的命令将文件发送到打印机:
:write !lpr
(注::write! lpr与:write !lpr这两个命令的不同,前才是强行保存文件而后者则是将文件发送到打印机)
命令:uddate与命令:write相类似,所不同的只是如果缓冲区没有被修改,那么这个命令就不会起作用了.
:read命令将会读入一个文件.这个命令的一般格式如下:
:line read file
这个命令会将名为file的文件读入并且插入在line后面.如果没有指定文件,那么就会使用当前的文件,如果没有指定要插入的行,那么就会使用当前的行.
与:write命令相类似,:read命令可以使用一个命令而不是一个文件.如果要读入一个命令的输出并插入到当前行的后面,我们可以使用下面的命令:
:line read !command
我们在以前的学习曾学过如何在寄存器中录制宏.如果我们要在命令行中使用这些宏,我们可以用下面的命令来执行寄存器中的宏内容:
:line@register
这个命令会将光标移动到指定的行,然后执行寄存器中的内容.这就意味着下面的命令执行上一次的命令行:
:@:
如果要执行上一次的:@register命令,我们可以用下面的命令:
:line@@
命令:>使得文本右缩进,:<命令使文本向左缩进.例如下面的命令将会使第五行到第十行向右缩进:
:5,10>
:change命令与:delete命令相类似,所不同的只是他还同时执行:insert命令,也就是有我们可以同时输入我们要插入的文本.
命令:startinsert命令可以开始插入模式,就像是我们在正常模式下执行i命令一样.
如果我们要将几行合并为一行,我们可以使用命令:join,在这个命令的执行中将会使用空格来分隔这几行.如果我们不希望加入空格,我们可以用下面的命令来合并:
:join!
下面的命令可以将指定的行的文本复制到寄存器中:
:range yank register
如果没有指定寄存器,将会使用未命名寄存器.
:put命令会将寄存中的内容粘贴到指定的文本行的后面.例如要将寄存器中的内容粘贴到第五行的后面,我们可以用下面的命令:
:5put a
如果要将文本放在这一行的前面,我们可以用下面的命令:
:5put! a
:undo命令会撤销上一次的命令操作,与u命令相类似.而:redo命令会重做撤销的操作,与命令CTRL-R命令相类似.
如果要标记一行的开始,可以用下面的命令:
:mark {register}
如果指定了行,那么那一行将会被标记.命令:k将会起到同样的作用,只是我们不需要在寄存器名前加上一个空格.例如下面的命令:
:100 mark x
:100 ka
命令:preserve可以将整个文件写入swap文件.这就使得我们可以在没有原始文件的情况下来修复我们的编辑部分.
如果我们要执行单一的Shell命令,我们可以用下面的命令:
:!cmd
cmd就是我们要执行的系统命令.
例如要查看当前的日期,我们可以用下面的命令:
:!date
如果我们要重复上一次的Shell命令,我们可以用下面的命令来做:
:!!
最后下面的命令可以挂起Vim而进入命令提示行:
:shell
现在我们就可以执行各种的系统的命令了.在我们完成我们的工作以后,我们可以用exit命令回到Vim编辑器.
下面的一些选项可以控制命令的执行:
shell 我们要执行的命令名
shellcmdflag 跟在命令后的标记
shellquote 在命令中的引用字符
shellxquote 命令中的引用字符和重定向
shellpipe 使用管道的字符串
shellredir 重定向输出的字符串
shellslash 在文件名中使用向前的斜线(只在DOS中使用)
命令:history可以当前命令模式下的命令历史
Vim编辑器可以记录各种命令的历史,下面的标记指出所记录的历史类型;
c cmd : 命令行历史
s search / 查找字符串历史
e expr = 表达式寄存器历史
i input @ 输入行历史
a all 所有的历史
如果我们列出所有的历史,我们可以用下面的命令:
:history all
:history命令的一般格式如下:
:history code first,last
如果没有指定first和last,那么就会列出所有的命令.first参数默认是指历史第一个输入的,而last就是指最后一个.负数是指由历史的结束处向前的数的第几个.例如-2是指最后个命令的输入.
例如下面的命令列出第一个到第五个的命令行历史:
:history c 1,5
而下面的命令则是列出了上五次的查找历史:
:history s -5
history选项可以用来控制记录的历史命令数.例如我们要将记录的历史命令数增加为50,我们可以用下面的命令:
:set history=50
Vim编辑器可以记录上几次的错误以及在屏幕最后一行显示的信息.要查看这些信息,我们可以用下面的命令:
:messages
下面的命令可以使得信息的输出在显示在屏幕的同时会拷贝到一个文件中:
:redir > file
如果要停止拷贝,可以使用下面的命令:
:redir END
这个命令在保存调试信息时会显得更为有用.
我们还可以用:redir命令将输出追加到文件中:
:redir >> file
:normal命令可以使我们执行一个正常模式下的命令.例如下面的命令是将光标下的单词改为DONE:
:normal cwDONE
在行这些命令时要求命令必须是一个完整的命令.如果我们已经挂起Vim然后执行命令时,Vim显示全直到命令完全时也会发生变化.
下面的命令会将当前的文本写入文件,然后退出:
:exit
如果我们使用!选项,即时这个文件被标记为只读,那么Vim也会强行保存.
我们还可以在命令行指定一个文件名,那么当前的内容就会在退出以前写入我们所指定的文件,例如下面的命令:
:exit save.txt
如果我们只是想着将文件中的一部分保存到另一个文件,我们可以指定一个范围来保存.例如要保存100行,我们可以用下面的命令:
:1,100 exit save.txt
下面的命令与:exit命令相类似,不同的是这个命令总是会保存文件:
:range wq! file
而:exit命令只是在文件发生改变时才会保存.