Vim编辑器教程.doc_第1页
Vim编辑器教程.doc_第2页
Vim编辑器教程.doc_第3页
Vim编辑器教程.doc_第4页
Vim编辑器教程.doc_第5页
已阅读5页,还剩32页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Vi/Ex编辑器教程第一章 Vi基础为什么选择Vi一个贴心的编辑器。小何是个程序员,在一公司里与他人做共同维护的工作。刚从别人那里接手了一个大的模块。这个模块的代码真是满目疮痍啊,到处是修补的痕迹。而且看上去这些“意大利面条”式的代码补得不怎么牢靠;就在昨天这个模块彻底地崩溃了,使得这个部门几乎瘫痪。在一夜地奋战过后,小何终于在今早使这个模块又能运转了在他打算出去买早餐时,该公司信息部门的副主管走过来了“小何,这次的修复干得很好,辛苦你了。不过现在我需要这次崩溃的技术数据,要整理过的,马上。信息委员会的董事会早上召开了一个紧急会议,目的是评估问题是否在可控制的范围。如他们把矛头指向我,那我就倒大霉了。我需要有一些可以在投影机上播放的技术资料,以便转移他们的注意力。 “他们很可能会让我讲一讲日志中导致这次崩溃的错误代码的相关记录对了,这部分内容是记录在/oltp/err/m7中,日志是使用追加的方式因此最新的报告会记录在文件的底部。那些人对日志中旧的部分不感兴趣,他们认为那是历史了。另外除了市郊的火车时刻表外,他们不习惯看东西是从下往上的。所以你得重新整理一下顺序。“看一下,这是日志文件: 374a12 44872 130295/074457 nonabort 5982d34 971 130295/221938 nonabort 853f7 2184 140295/102309 abort “恩向他们解释第二栏的数据等于跟他们说我们早知道这些缺陷的存在,只等着模块崩溃了那是找死。你在编辑时记得,记得将第二栏中除首尾的两个数字外的其他数字删除。“对了,他们看那些看腻了后会想仔细地看一下Lint报告的。上个月我才跟他们说我们的代码无懈可击,现在我得说服他们相信这个模块现在还在不断输出的错误消息都是些无关紧要的小毛病引起的。你得对修补后的代码进行Lint检测然后把输出结果与源文件合并。方法是先在输出的结果中找这种的信息: Line 257: obsolete operator +=然后把重要的部分放在源文件中相应行的末尾。中间用分隔符如XXX分开,方便查找。没什么能比足量的源代码更能让会议提早结束了因为他们根本不知从何看起。“快去做吧。会议在35分钟后就开始了。” 然后我们的副主管就走了。他是暗笑着走开的,因为他已经打好算盘了他知道在这么短的时间里没人能做好他要求的那么多的编辑任务。这样等会他就不用费力的解释这次的崩溃了,他只需把责任推给他的下属。我就跟信息委员会的人说:“我已经跟程序员说过要在9:30之前做好报告了,而且讲很清楚了。但我刚问他时他说还没弄好而且不知何时会弄好。”然后:“这些程序员就是不能意识到时刻向管理层报告进度就跟程序中的每一个字节一样重要!”不过小何在与上级的角力中并非完全落于下风,他还有秘密武器:vi将文件中的行倒置对这个编辑器而言只是小菜一碟。以下的八个按键(在以下的文章中用(ret)表示按回车键): :g/m0 (ret)就能完成这个工作了。将文件中所有行的第二栏首、尾以外的其他数字删除也只要一行命令: :%s/( * 0-9)0-9*(0-9 )/12 (ret)那结合Lint报告与源代码呢?就算这种工作Vi也能自动做到自动化。这条命令: :%s/Line (0-90-9*): (.*)/1s;$; XXX 2 (ret)会把Lint的报告文件改为编辑器的脚本,只要在源文件中运行此编辑器脚本就能达到我们要的编辑目的了。小何只用了几分钟,输入了几行就避免了当冤大头。他现在还剩一些时间可以考虑怎样才能防止副主管推诿责任他可以先到街对面的咖啡厅,等在会议开始的那时再再出现在会议厅中,并用在场每个人都听得到的方式告诉副主管:“你要的那些文件就在斜杠temp斜杠hal文件夹中”。这篇教程的写作计划。我想写给那些对vi/ex有初步认识的编辑器用户。即你已经对一些类似“Vi入门”之类的书里教的那些普通的内容已经熟悉了。这种Vi的书籍在市场上泛滥却很少触及更深层次的东西。在这系列的教程中我们会深入的探索一些较不为人知的vi/ex的用途。其中有不多的技巧是通过一些我们经常使用的编辑功能来实现的,但我们确很少注意到这些技巧举例来说,用 global 命令来对处理的每一行做记号。同时我还会对关于Vi的许多常见的误区进行阐述。要做到这些,我会很详细的解释里面的每个部分。我会在有必要的地方出些习题帮助理解。同时为了让你不至于被过多的模糊的信息所淹没,我会将这篇教程分成很多小块。然后用平稳合理的节奏将教程一篇篇地放到我们的网站上。关于这个编辑器的几个基本概念要真正理解这个编辑器的威力,你得对编辑器有一个基本的认识。它的许多功能便是筑在这些基础的概念上面。这个编辑器被误用的一个原因是许多用户包括有经验的用户,没有分清什么是它的本职而哪些工作不适宜用它来完成。这里有一个这个编辑器本职功能的参考列表:第一,编辑器严格地用来表示通用目的的编辑器。它不对文本进行格式处理;它不需要一个字处理器的支持;它不需要内建特殊的功能用来编辑十六进制、图形、表格、大纲或是支持任意一种编程语言Lisp除外。它是二合一的编辑器。在可视模式(Visual Mode)11 注意这里的可视模式相当于Vim的一般模式和插入模式而不是Vim下的可视模式/圈选模式(也是Visual Mode)下,它是个比大多数的编辑器好的全屏编辑器,并且比那些同样支持一堆屏幕编辑命令的对手要运行得更快。它的行模式2(Line Mode)2 行模式不是命令行模式的缩写。Ed/Ex类的编辑器中编辑是面向行的,用户使用命令对指定行进行编辑。这一类编辑器通常称为行编辑器。Vi的行模式即是使用Ex进行编辑的一种模式使字处理器和简单的交互式编辑器的“全部查找和替换”功能相形见绌。它的仅有的对手是非交互式的编辑器,如Sed ,使用这种编辑器你得事先准确的知道自己要做哪些编辑。但在vi/ex中,这两种工作方式被很发好地结合起来了。我用过的编辑器还没有哪一个会比vi/ex好当把它的两方面的优势结合起来时。最后,这个编辑器只有抱着不怕苦不怕难的精神完整地学习过才能够用得得心应手。它的功能太多了,你根本没法在一或两个钟头里掌握。它又很特殊,用一个礼拜的时间都没法精通这个编辑器。但它的威力就在那儿,只有深入钻研的人才能掌握。这种威力很大一部分要靠对编辑器的个性化编程来实现:这不太容易,对熟练的用户而言它通过编程来扩展功能的能力要比任何的其他编辑器来得强或许(可能)只有Emacs例外。搜索式样在这个编辑器有有许多的功能,能通过使用字串式样的搜索来指定功能在哪里执行,范围有多大。这些搜索式样很能说明这个编辑器带有明显的Unix风格,但在搜索式样的细节上仍与其他的Unix工具有所区别。搜索式样功能在行模式下与可视编辑模式下大多数情况下有一样的使用方式,只有少数例外。但在输入搜索式样时怎样让编辑器根据不同的需要进行搜索呢?从当前位置开始搜索。通常我们用搜索式样是为了移动到文件中的另一个地方,或者把编辑命令的范围从当前位置扩展到式样所指明的位置。(在编辑模式下你还可以用一个式样的位置到另一个匹配式样位置作为执行动作的范围,但两个式样都是从当前位置开始搜索。)如果你想要从当前位置往下搜索(一直到文件尾),在搜索式样前面和后面加上一个斜杠(/)。因此如果你想要从当前位置开始查找文件中出现下一个字串“j+”的位置,输入: /j+/ (ret)就行了。也可以这样: /j+ (ret)注意,在式样与回车键(ret)之间没间隔,回车本身表示搜索式样的结束,所以第二个斜杠可省略。如果当前模式是可视模式,使用 ESC 键与回车键一样可以用来表示搜索式样输入完毕,所以在可视模式里如下命令 /j+ (esc)与之前的命令的作用是一样的。要向上搜索(回搜),在式样前后加上问号而不是斜杠。回搜与向下搜索使用同样的规则,因此 ?j+? (ret) ?j+ (ret) ?j+ (esc)都可用于回搜一样的字串。无论哪种方式你都只用了一个键来提交并确认搜索的式样和搜索的方向。可别以为回搜时在文件中找到的匹配项都是在当前位置以上,当前位置以下的匹配项也会被搜索到,反之亦然。编辑器在往回搜索时先在当前位置逐渐向上搜索,但当它到达文件的顶部(第一行)或底部(最后一行)时如果还没发现匹配项,它就会从文件的另一端开始往同一方向继续搜索。也就是当你用问号进行回搜时,编辑器会从当前行不断地往上找。如果到第一行还没找到匹配项,那它就会从最行一行开始继续搜,然后是倒数第二行,倒数第三行依此类推,一直搜到最初开始搜索的位置(如果一直没找到匹配项的话)并停止搜索。或者当你往下搜索时一直到最后一行也没找到匹配项,编辑器就会从第一行开始继续搜索,然后第二行,第三行如果你不想在搜索从文件的一端绕到另一端去继续,你需要一条行模式的命令: :set nowrapscan (ret)这可以禁止当前会话33 Vi可以同时打开多个文件,会话session就是当前编辑中的所有文件中的绕回搜索。要在编辑时恢复绕回搜索功能,输入 :set wrapscan (ret)就可以了,看你想开开关关几次都可以。“查找全部”搜索。目前为止,我只讨论了查找搜索式样的一个匹配项的方法往指定的搜索方向查找在文件中距当前位置最近的一个匹配项。但搜索还有一种其他形式。这种形式的搜索主要用于行模式命令,如global和substitute。这种搜索方式找到文件中(或在文件中的指定部分)包含式样的所有行并对它们进行操作。在使用global和substitute时不要被它们搞晕了。在命令行中两种形式的搜索方式经常混合使用。但“查找一个匹配项”的式样一般置于命令名或命令缩写前而“查找全部”的式样则放在命令后。比如,在以下命令中: :?Chapter 10?,/The End/substitute/cat/dog/g (ret)前两个式样分别用来匹配在当前行之前且距当前行最近的包含“Chapter10”字串的行和在当前行之后的第一个包含“TheEnd”字串的行。请注意每个地址(即包含式样的行的地址)只对应一行。以半角逗号隔开表示substitute命令作用于这两行和这两行之间的所有行。但紧跟着substitute命令的式样指示命令对命令作用范围内的所有字串“cat”替换成“dog”。除了字面上意义的不同外,两种形式的搜索也使用不同的分隔符用以标识式样的开始和(有些时候需要)结束。对“查找全部”式样而言不需要指示往前或往后搜索。因此式样的分隔符不仅限于问号和斜杠,还可以用半角的标点符号几乎所有的标点都可以,因为编辑器自动识别命令名后的第一个标点符号为该命令中的分隔符。因此这几个替换命令 :?Chapter 10?,/The End/substitute;cat;dog;g (ret) :?Chapter 10?,/The End/substitute+cat+dog+g (ret) :?Chapter 10?,/The End/substitutecatdogg (ret)都是一样的。(最好不要使用在命令中有特殊意义的标点,如感叹号经常用作一个开关选项出现在命令名的后面。)使用其他标点作分隔符在搜索式样本身包含“斜杠”时就显示出了其优点。例如,当我们要将文本中所有的连续的两个“斜杠”用“-”隔开,即将“/”替换为“/-/”。很明显这样做: :?Chapter 10?,/The End/substitute/-/g (ret)是不行的。这个命令会将前三个斜杠视为分隔符,而对后面的所有字符视而不见。这个问题可以用“反斜杠”来解决: :?Chapter 10?,/The End/substitute/-/g (ret)但这个比上一个错误的命令还难正确地输入。当用其他的标点作为分隔符时 :?Chapter 10?,/The End/substitute;/;/-/;g (ret)容易输入也更容易理解该命令的作用。简单搜索式样。最简单的搜索式样是直接输入要编辑器查找的字符。就如:“thecat”。但这里有几条注意项:1. 这样方式搜索字符时并不只有以这些字符组成的单词会匹配式样。它会匹配“wefedthecatboiledchicken”也会匹配“wesailedalithecatamarandownthecoast”,就看它先碰到哪个。 2. 至于会否匹配“The Cat”则要看你是否设置了一个叫 ignorecase 的编辑器变量。如果你未改变默认设置,带有大写字符的这个版本将不会被匹配。如果你希望在式样中不区分大小写,在行模式中输入以下命令 :set ignorecase (ret)要区分大小写,输入 :set noignorecase (ret)3. 上面的搜索式样肯定没法匹配“the”在一行行末而“cat”在下一行的开头的这种情况: and with Michaels careful help, we prodded the cat back into its cage. Next afternoon several至于字与断行之间是否有空格并不重要。对于一个“面向行”的编辑器而言要用找出一个式样来匹配跨行的字串是不大可能的。4. 搜索由哪个位置开始取决于你使用的编辑模式。在“可视”模式的搜索由光标位置的下一个字符开始搜索。“命令行”模式下搜索由当前行的邻近行开始搜索。 字元。Vi/Ex有所谓的“字元”或叫做“通配符(wildcards)”:在搜索中有特殊含义而不表示其字符本身。如字元“.”“*”,在 /Then .ed paid me $50*!/ (ret)可用来匹配以下的任意一项: Then Ted paid me $5! Then Red paid me $5000! Then Ned paid me $50!或无数的其他字串。正是字元赋予了搜索式样威力,但前提是必须对字元有所了解。要了解这些,你得知道如何使用反斜杠()字元来控制字元“通配”功能的开与关。许多情况下,一个搜索式样中的字元如果没有前置一个反斜杠时使用的都是它的字元值都是作为通配符出现的字元,而前置一个反斜杠则用来表示用作字元的字符本身。反斜杠字元本身就是一个例子,当它单独使用时它使用的是它的字元值(即作为有“通配”功能的字元),就算在紧帖它前面的是一个普通的字符也是一样。如果要在搜索式样中搜索反斜杠这个字符则要在它之前添加一个(使用字元值的)反斜杠用来使之表示反斜杠自身。就是说要搜索“ab”,输入 /ab/ (ret)作为搜索式样。如果你输入 /ab/ (ret)反斜杠会被当做一个字元也不会有什么做用(因为 b 不是一个字元)因而这个搜索式样找的字串实际上是“ab”不经常使用的字元则与此相反。这些字元如未前置反斜杠则用做一般的字符。前置反斜杠方可使用这些字元的元值。如,在 /cat/中左尖括号()是一个字元。在 /cat/中它就表示一个尖括号字符。这些特殊的字元会在下面列出。最后还有第三种类型的字元最难搞掂的一种。一般情况下,在搜索式样中这些字元的元值是默认启用的,前置一个反斜杠可让它们做为一个普通的字符:就如同我们的第一个例子,反斜杠自身的例子。但如果你将一个名为magic的编辑器变量的默认值更改了,它们的工作方式恰恰相反前置一个反斜杠来启用字元的元值:就像我们的第二个例子,左尖括号的例子。(没理由要将magic关掉。)这些最奇怪的字元也会在下面列出来。还有不要忘了那些用来标识搜索式样开始或结束的标点符号,不管是斜杠问号还是其它的标点如果它也出现在搜索的式样中作为一个被搜索的字符之一,那你需要前置一个反斜杠来防止编辑器将之解读为式样的结束符号。字元表. 在搜索式样中一个半角句号可匹配一个单一的字符,不管是字母还是数字或标点符号。事实上除了换行符(newline)外,“.”可用来匹配任意的ASCII字符。因此要查找“defaultvalue”时考虑到它也可能被拼写为“defaultvalue”或“default/value”又或者是“default_value”等等,搜索式样可以用“/default.value/”。当编辑器变量“magic”关闭时,你必须加上反斜杠让句号使用它的元值。 * 星号,结合星号之前的一个字符,可以用来匹配由星号前的那个字符组成的任意长度的字串(包括长度为0的字串)。因此搜索字串“/ab*c/”可以匹配“ac”、“abc”、“abbc”或者“abbbc”,依次类推。(要查找至少包含一个b的字串,可以使用这个搜索字串“/abb*c/”。)如果星号字元紧跟在另一字元之后,则匹配任意长度的前一字元所匹配的字符。这意味着“/a.*b/”将会找到一个在“a”与“b”之间有任意长度(包括长度为0)的任意字符的字串。当编辑器变量“magic”关闭时,你必须加上反斜杠让星号使用它的元值。 当脱字符作为搜索式样的第一个字符时表示匹配式样的字串必须是在一行的开头处。它不代表在一行开头处的任何字符(或者说它匹配一行开头空字符)。当它不是一行开头的第一个字符时,它表示的是一个普通的字符(未使用元值)。所以“/cat/”会找到以“cat”开头的行而“/cat/”找到包含“cat”字串的行。 $ 当美元符作为搜索式样中的最后一个字符时表示匹配的字串必须在一行的末尾。其余同上。 当一个搜索式样以一个反斜杠接左尖括号开始时,表示从一个“简单”词的开始部分开始匹配。当在式样的其他位置出现时它并不是做为一个字元。(这个编辑器中,一个“简单”词可表示一个或多个数字、字母组成的字串,也可表示一个非数字或字母与任何的非空白字符组成的字串(译者:空白字符表示空格、制表符、换页符等等,所以“shouldnt”包括了三个“简单”词。)“/cat/”匹配字串“thecat”或“tom-cat”中的后三个字符,但不会匹配“tomcat”。要移除左尖括号的元值让它成为一个普通的字符,只要去掉前面的反斜杠:“/cat/”会匹配字串“ 在一个搜索式样的末尾一个反斜杠接右尖括号表示匹配只发生在一个“简单”词的末尾。其余同上。 波浪线用来表示substitute命令中的后一个字串,这个命令可以在行模式下输入或在可视模式下通过前置一个半角冒号(“:”)再输入运行。举例而言如果你的上一个替换命令是“s/dog/cat/”那么“/the/”搜索式样将会匹配“thecat”。但substitute命令的输入字串自身也能用字元如果你在之前使用其中的一个字元那么搜索式样中使用波浪线会出现错误信息或匹配结果你要的不一致。当编辑器变量magic关闭后,你得加上一个反斜杠才能使用它的元值。 字符集合。在搜索式样中还有一种字串元(多个字符组成的字元)。当多个字符使用半角方括号括起来时,可用来匹配括号中的这些字符中的任意一个。“/part123”将会匹配“part1”、“part2”或“part3”。在关闭了编辑器变量ignorecase(默认情形为关)后,这个功能经常用来查找可能含有大写的字串。输入“/Ccat/”会找到“Cat”和“cat”,而“/CcAaTt/”则会匹配任意的大小写组合的“CAT”。(可用来匹配在输入“CAT”时不小心按到Shift键的情况,最后一个式样还能找到“CaT”、“CAt”等字串。)字串元的功能还能进一步扩展:可在其中使用字元。如果方括号中的第一个字符是脱字符,与字符集合正好是相反的意思(即补集)。现在该字串元匹配任意没出现在括号中的字符。式样“/ /”匹配未以空格开始的行。在字符集合中如果脱字符不是方括号中的第一个字符时只表示一个普通的脱字符。方括号中的短杠(连字符)也可做为一个字元。当它出现在两个字符中间,并且前一个字符的ASCII值要低于第二个时,它起的作用就如同你依ASCII次序由前一个字符逐个输入字符一直到第二个字符到方括号中一样。所以“/0-9%/”匹配一个数字紧接着一个“%”号的字串,它与“/0123456789%/”是一样的。搜索式样“/a-z/”匹配任意的小写字母,而“/a-zA-Z/”匹配任意字母,不管是大写或小写的字母都能匹配。两个在方括号内使用的字元可以同时使用:“/A-Z/”会匹配除大写字母以外的任意字符。当短杠出现在括号中的第一个或最后一个位置时它没有元值。当一个“字符-字符”的字串中的第一个字符的ASCII值比后一个字符高时,式样搜索时会忽略这两个字符及其中的短杠,所以“/ABz-a/”与“/AB/”是一样的。在字符集合中使用反斜杠的方法要复杂一点。如果有一个右方括号做为字符集合中的一部分出现在方括号中,必须在该右方括号前面加上反斜杠。不然编辑器会误认该括号为字符集合的结束标识。当然如果你要在字符集合中使用反斜杠你也必须在前面加上另一个反斜杠,而如果你希望括号开头的脱字符和字符中间的短杠作为字符集合的一部分不使用它们的元值并且也不想将它们移到这个方括号的其他位置时,你也可以在它们之前加上反斜杠。在搜索样式的其他位置使用作为普通字符的左方括号时可在前面加上反斜杠,否则编辑器会以为那是一个字符集合开始的标识。最后,如果关闭了magic,你在你要开始一个字符集合时你得在左方括号前加上一个斜杠。第二章:行模式地址无论何时当你使用编辑器命令对当前文本的文本进行操作如删除一些文本;将小写字母改为大写字母;写入文件(部分保存)等等,的时候你得让编辑器知道你要对哪一部份文本进行操作。少数的命令有内建的地址,大多数的行模式命令在用户未指定地址时会使用默认的地址。但仍有许多情形下你必须知道如何给编辑器地址和给它什么样的地址。许多行模式命令与可视模式下的相应命令是一样的,它们是完成同样工作的不同方式。重复的命令集的好处源于行模式与可视模式所提供的两种截然不同的寻址风格。截然不同的两种寻址方式意味着对于一种方式难于完成的编辑任务对于另一种方式可能只是小菜一碟。我这样一直提“行模式”,你可能会好奇是否真有一种单独用于行编辑的模式。答案是:当然有。这种模式下你的屏幕不会为当前编辑文件的文本所占据,这个模式给你一个行模式的命令提示符半角冒号(:),并只在屏幕上显示文件中的一特定行。这种模式给人的感觉就像是在shell提示符下使用UNIX命令一样。现在已经很少人在行模式下编辑了,主要是因为在可视模式下你还能调用大多数的行模式命令,但在行模式下却没法使用可视模式命令。也可能因为可以在屏幕上看到文件内容,并能即时查看修改的文本的这种WYSIWYG(所见即所得)的感觉,更易于为大众所接受。但在有些情况下你仍需要暂时地使用行模式。要以行模式运行这个编辑器时可在Shell下输入“ex”而不是“vi”来启动这个编辑器。如果你已经在这个编辑器的可视模式中时可输入“Q”来进入行模式。要回到可视模式,输入“vi”然后按回车。“vi”显然是个行模式命令那你知道为什么在输入“vi”回到可视模式时我没有在前面加上半角冒号吗?原因是在行模式下输入命令时并不需要那个冒号。输入冒号甚至有害无益,行模式下如果在命令前输入冒号,那么在冒号和命令(不管是使用完整的命令或使用缩写的命令)之间不能有地址也不能有空格什么也不能有。基于以上的原因,在下面的行模式命令中将不带冒号,你知道的只有在可视模式下使用行模式命令才需要在命令前加上半角冒号。同时每个命令后我不再用“(ret)”来提醒你该命令要以回车键来结束,因为你应该已经注意到了不管是行模式还是可视模式下使用行模式命令都要以回车键来结束。有些人可能会问为什么我要使用完整的命令形式,并使用了许多空格来分隔命令;为什么不使用简略的缩写命令的形式。看看下面的例子,有两行命令: global/move0 g/m0有一样的作用,但第二个输入起来肯定要快些,那为什么在本教程中使用第一种形式呢?因为更长的版本更容易理解特别是当我在演示一些新概念时,并且这里面的内容至少对某些人来讲是新的。你很快会开始学写编辑器脚本,如果以简洁的风格写就脚本的话,对未来维护脚本的程序员而言这些脚本会跟APL语言一样难懂。所以你最好能了解一下这些命令的完整形式。在我介绍这些个行模式命令时我会告诉你该命令的完整名称和一至二个的缩写名称。行模式寻址单个地址。通常一个行模式命令只需要一个地址。一个地址就是指某一特定行,用以指示某些命令如删除命令(delete)或替换命令(substitute)只对指定行进行操作。对于像插入命令(insert)或读入命令(read)这种在当前行前或行后置入文本的命令而言使用多个地址则没什么意义。搜索式样都是合法的行模式地址(在第一章中我们已经讨论过搜索式样)。地址要放在命令的开头,要置于命令名之前(如果在可视模式下使用行模式命令时地址则要放在开头的半角冒号之后),所以: ?thecCat?delete会将上一个包含字串“thecat”或“theCat”的行删除,而: /GLOSSARY$/readgloss.book在当前编辑的文件中从当前行开始往下找一行只包括一个单词“GLOSSARY”的行,并将“gloss.book”文件的内容置该行之后。要重用与上次同样的搜索式样作为地址有两种简写形式。输入“?”或“/”告诉编辑器使用上一次使用过的搜索式样,而“?”与“/”分别表示不同的搜索方向用以代替上次使用的搜索方向。也即,如果你输入了: ?thecat?yank /delete ?print第二条命令会向下搜索包含“thecat”的行并删除,即使你最早使用搜索式样时的搜索方向是向上。第三条命令会向上(往回)搜索找到包含“thecat”的行并打印,这(凑巧)与最初搜索的方向相同。但这个通过简写形式(?或/)重用的搜索式样也许不是你用过的用来搜索和定位行的式样。如果你在某个式样搜索结束后运行一个替换(substitute)命令,那么此时重用式样使用的是替换命令用来指代替换文本的式样而不是上一个用来定位行的搜索式样。如果你的替换命令用一个搜索式样开始作为进行替换操作的地址,然后在命令中指定要进行替换的式样结果也是一样的重用搜索式样时用的还是后一个式样。因此如果你输入了: /thecat/substitute/inthehat/onthemat ?delete这时第二个命令会删除上一个包含“inthehat”的行。要确保重用的式样是上一个用来定位行的式样(而不是上一个用来替换的式样)可以使用“?”和“/”这两种简写形式来向上和向下搜索。在其它的情况下这个两种简写形式与输入“?”“/”的用处是一样的。行号也是有效的行模式地址。编辑器会自动地为文件中的每一行进行连续地编号,这种编号是动态进行的,也就是当你增加或删除行时编辑器会对插入和删除点后的所有行重新编号。所以如果你对第46行的一些文本进行了修改并删除了第11和12行时,你所修改的那一行现在变成了第44行。如果你又在第17行后增加了10行新行后,你修改过文本的那一行现在又自动变成了第54行。所有的行号都是连续的不会有漏掉的或重复的行号,因此文件中第n行的行号总是“n”,就是第七行的行号总是7,依此类推。(有许多方式可以用来显示行号,这些内容我会在后面的教程中详细的说明。)输入以下命令就能删除文件中的第153行了: 153delete在行号的周围不需要使用任何的分隔符,除了搜索式样外在任何的地址周围都不用使用分隔符。还有两个用符号表示的行号和一个虚构的行号也可用于行模式中的寻址。只要在“缓冲”(译者:可简单理解为当前编辑文件)中有任何一行文字(也就是你没有编辑一个尚未存在且未输入任何文本的文件时),编辑器就假设你就在这两个符号所表示其中一个地址中,通常最后一行会受最近一个命令所影响。一个半角句号或说是一点(.)是代表当前行的地址符号。而文件中最后一行的地址符号是美元符号($)。因此如果你输入了: .writegoodlines $delete第一个命令会将当前行导出并添加到名为“goodlines”的文件末尾,而第二个命令会将编辑中文件的最后一行删除。有几个命令会在你给的行地址后置入文本:append(附加命令)命令就是其一。为了将文本置于文件的开头(如果你想把文本置于文件的开头的话),这几个命令还能接受一个虚构的行号零(0)作为它们的地址。如果你想在文件中所有文本之前输入一些文本的话,以下的任一命令都可以做到: 1insert 0append(注意:insert和append命令是不能在可视模式下通过前置一个冒号运行的少数行模式命令之一,因为加上要插入或附加的文本这两个命令要占用不止一行的空间。)自己设定的行址。你可以为行分配小写字母来作为行址,并且可以随时改变这种分配。你甚至可以通过一个特殊的地址来返回上一次跳转的行这个地址是自动分配的。用小写字母标识特定行有许多方法,这些方法依行模式和可视模式的不同而有所区别。在后面的教程中我会逐一说明这些方法。一行一旦被做了标识则指代该行的行模式地址为半角单引号紧跟着用于标识行的小写字母。输入: bprint会在屏幕上显示你先前用字母“b”标识的行,不管该行与当前行的相对位置为何都能显示该行。一个字母只能用来标识一行,所以不用告诉编辑器向上或向下搜索编辑器总能找到那行。编辑器自己也会做一些行标识。任何时候当你使用非相对地址从一行跳到另一行时,编辑器会将你原先的行址标识起来。(“非相对地址”指不是用当前行与原来行之间的间隔行数来表示的地址) $ /thecat/ 358 ?glossary?+7 b都是非相对行址,如果你使用这些地址在行之间移动,编辑器会标识你在移动之前的所在行以便将来使用。如果你要回到那一行只需输入两个连续的半角单引号: 理论上,这个地址可以做为一个行模式地址与行模式命令一起使用。但当你由于误操作而移动到文件中的其他位置时,很难肯定你上一次使用非相对地址移动后保留的行标识是否未受影响除非你对这个编辑器很熟悉。对上面的各种方式表示的地址进行修改有两种方法。简单一点的方法是为地址加上偏移量,用加号(+)或减号(-)来为地址增加或减少一定数目的行数。规则是地址后的每个加号都指示编辑器在当前文件的指定地址处下移一行,而减号则相反。依这一规则下面的三个地地址表示的是同一行。 35 37- 30+你可能不想用数数的方式来修改行号表示的地址,除非你的数学确实很糟希望编辑器能代你来进行加减运算。但这种数数方式表示的偏移量能与所有的行模式地址一起使用,但最经常的是在搜索式样中使用。幸好,这些加号和减号也有简写形式。一个加号或减号紧跟着一个数“n”(一位数或多位数)与“n”个加号或减号表示的是一样的偏移,因此以下的两个地址是一样的: /registerlong/+ /registerlong/+4注意第二个例子中的“4”表示的并不是“行号4”,它只有单独出现时才作为一个地址。在加减号后的数表示的是从前面指定的地址处(上面的例子中这个地址是“/registerlong/”)向下或向上移动的数目(如果前面没有指定的地址则从当前行开始算)。还要注意这是行模式命令中少数不能插入空格的情况之一。加减号与数字间不能有空格,不然编辑器会在无提示的情况下对行肯定不是你要的那几行,进行操作。第二种风格的地址修改方法可在进行一些复杂的搜索时使用。假设你想向下定位某以“WARNING!”开头的行并删除该行,但有从当前行以下有多行是以“WARNING!”开头,你要找的第二个符合条件的行。可以使用下面的任一命令: /WARNING!/;/WARNING!/delete /WARNING!/;/delete两个搜索式样中的分号(;)告诉编辑器先用一般的方式找到第一个搜索式样的位置,然后从那个位置开始搜索第二个式样。在上面的情况中,第一个搜索式样先找到当前行以下以“WARNING!”开头的第一行,然后第二个搜索式样指示编辑器继续找下一个(也就是第二个)符合条件的行。分号两边的式样都可以独立作为一个有效的地址。很重要的一点是上面的命令虽然将两个搜索式样结合使用,却并不是让编辑器删除两行。分号在这里的作用是让第一个式样成为一个停靠站,编辑器从匹配第一个式样的行开始搜索匹配第二个式样的行,并只删除第二个式样所匹配的行。简言之,这个看上去像表示两个行的两个地址实际上是一个地址用以指代某一行。(这并不是这个编辑器的官方文档的说法,但在这一点上官方文档显然是错的。)但好戏才刚要上场呢。没有人限制说你只能使用两个地址。我曾经一次用完十个地址来定位某一行,当然这些地址都要用分号隔开。看这个例子: ?Chapter3$?;/Bibliography$/;/Spinoza/;/Monads/将会找到“Spinoza”(斯宾诺莎)的作品中第一部标题中包含“Monads”的著作。编辑器先找到“Chapter3”(第三章)的“Bibliography”(参考书目)然后找“Spinoza”所在行,并从该行开始向下找包含“Monads”的行。同样在分号分隔的地址串中也没人限制说只能使用搜索式样形式的地址。如果你想找到第462行后的第一个包含词“union”的行,输入: 462;/就能把你带到那行了。并且其中的任何地址都能使用数字偏移,所以: 462+137;/registerint/-也是有效的地址串。但是不幸的是使用分号分隔的地址串仍有两个限制。较次要的一个问题是只有地址串后面的命令能接受第0行作为其地址时,才能在地址串中使用“行号零”。即,除非命令能在第0行使用,不然就算你的地址串由0行开始后又通过附加的地址指示对其他的行进行操作也不行。 0;/Spinoza/+;/Kant/delete这个用以确保搜索能找到文件中的第一个“Spinoza”的地址串看上去挺好,但实际运行下去会出现非法地址的“错误信息”。较主要的问题是:在地址串中用分号隔开的每个地址所表示的在文件中的位置都必须比前一个地址更靠后。(“地址表示的在文件中的位置”指在加上偏移量后地址所指代的行的位置。)地址表示的文件中的位置不能相对分号分隔的上个地址更靠前(即更接近文件顶部)。但这不意味着你不能在地址串中使用往回的搜索式样(即使用“?”做为式样的分隔符)。地址串中的第一个地址使用往回搜索当然是没问题的。而接下来的地址,只有当你确定使用回搜式样后实际找到的行要比前一地址更靠后时才能使用回搜的式样(做为地址)。比如在你知道某个特定的回搜必须在绕回到文件底部继续搜索才能找到匹配的行时就可以使用回搜式样。一般是这种情形: 1;?Spinoza?;/Hegel/yank在第1行回搜意味着搜索将绕回到文件底部继续,这就保证了所复制(译者:“yank”命令的作用就是复制行)的包含“Hegel”的行必定是在文件中的最后一个包含“Spinoza”的行之后。还有一种可在地址串中使用回搜的情况就是在回搜式样后加上偏移量。不过只有在你确定加上偏移量后指代的行在文件中的位置要比上一个地址表示的行更靠后时才能使用回搜。因此如果我想要确定第八章(“Chapter8”)中第一次出现“Hegel”的位置距第七章(“Chapter7”)中最后一次提到“Hegel”的行至少有120行的距离时,我可以输入: /Chapter8$/;?Hegel?+119;/如果一个使用上面这个地址的命令出现了非法地址的“错误信息”时,我就可以确定第七章最后一次提到Hegel的行距该章结尾还有120行以上的距离,这样我就可以知道第八章第一次出现他名字的位置正是我要找的。在这个例子中: /Chapter8$/;/Hegel/就是我的命令所需要的地址。使用往前搜索或者说向下搜索的情形与上面说的那些内容都差不多。向下搜索时可以使用负偏移只要使用负偏移后位置不会移到前一个地址表示的位置之上就行。但即使没有使用偏移或使用正偏移,回绕搜索也可能找到一比前面的地址更靠前的位置从而使向下搜索失败。定位一段文本两个地址也能用来表示一段文本。当两个地址用逗号隔开时与分号分隔的地址有着完全不同的意义。人们经常需要对一些连续的行使用行模式命令。比如你可能需要将一段文字从一个地方移到另一个地方。这时你可以给出该段文本第一行的地址,接着给出该段文本最后一行的地址,两个地址用逗号隔开。以下命令:14,17delete会将第14、15、16、17行删除。使用多于两个的用逗号分隔的地址是无意义的。如果你忽略了这点并使用了三个或三个以上的逗号分隔的地址则:编辑器使用前两个地址并忽略其余的。任何行模式地址都能与逗号一起使用。下面例子中的地址用法都是正确的: d,/struct/ 257,. ?Chapter9$?,$当命令与第一个例子中的地址段一起使用时,编辑器会找到你已用字母“d”标识过的行做为地址段中的第一行,并从该行开始逐行向下施加命令直到找到第一个以“struct”开头的行(包括这行)为止。第二个地址段的范围是从257行到当前行。第三个地址段先回搜到上一个只包含“Chapter9”的行,从该行到文件中的最后一行就是这个地址段表示的范围。这个技巧同样有限制。主要的限制是逗号后的(加上偏移量后的)地址必须比前一个地址的位置更靠文件末尾。有效的行范围中第二个地址必须是在第一个地址表示的行之后。 57,188delete是有效的命令,而类似的命令: 188,57delete只会制造出错信息。(如果两个地址正好指代的是同一行时命令也能正常执行。命令“默默地”对指定的那行进行操作。)当使用的行模式地址越来越复杂时,你可能会碰到第二个地址先于第一个地址的出错信息而你事先没料想到地址可能会有任何问题。这不是什么丢脸的事,解决的办法也很简单。在你仔细检查过地址并确定那些地址就是你要的地址时,只要交换一下两个地址的次序就行了。即,如果: 642,/inTable23/delete出错了,错误信息提示行的次序错误时: /inTable23/,642delete就能解决那个问题了。最后一个限制是当你在逗号两边使用搜索式样时,第二个搜索与第一个搜索一样是从当前行开始而不是从第一个搜索找到的行开始搜索。这个限制有个迂回的解决办法,这个办法需要将一个或多个分号与逗号结合使用。行模式下分号分隔的地址串的用法与单个地址一样,任何的单个地址都可以用地址串来代替。一个非常实用的技巧是在逗号的两边使用地址串,用以精确的定位行范围。我们说过分号分隔的地址串实际上表示的只是一行的地址,因此地址串也可以用作文本段的开始行或结束行。比如,在下面的命令中: /INDEX$/;/Xerxes/,$writetailfile ?PREFACE$?;/My7thpoint/,?PREFACE$?;/Insummary/-delete第一条命令将索引(index)的后半部分写入到一个新的文件中。第二条命令用来将绪论(PREFACE)中的某一节删除。这个技巧为上面说的限制即第二个搜索的起点问题,提供了解决方案。如果你想要逗号右边的搜索从前面搜索到的行开始,那就在你原来的第二个搜索式样(即逗号右边的搜索式样)前面加上第一个搜索式样并用分号分隔,例如: ?Stradivarius?,?Stradivarius?;/Guarnerius/ ?Stradivarius?,?;/Guarnerius/考虑到行模式下的地址串不能向上移动,我最好解释一下当分号与逗号一起使用(就像上面的例子)这些限制的工作机制。除了第一个地址外分号隔开的一系列的地址相对前一个地址都必须更靠近文件底部(不能向上移动或回搜)。但第二个分号分隔的地址串的开始地址在文件中的位置却可以先于第一个地址串(逗号前的地址串)中的任一地址。也就是这个“单向计数器”在遇到逗号后就重置了。在逗号两边使用分号分隔的地址串只要求第二个地址串的最终“着陆点”(即地址串最后确定的行,我们说过地址串中虽有多个地址但实际上表示的只是一行的地址)比第一个地址串的“着陆点”更靠近文件底部就行了,中间的各个地址的相对位置并不影响逗号的使用。为了讲清楚点,我们看两个奇怪的例子,这两个例子没什么实用价值但很能说明问题。 125;176;221,32;67;240上面的地址似乎是无效的因为出现了

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论