vi教程 |
1.6.1?vi 的工作模式 Vi 在初始启动后首先进入编辑模式,这时用户可以利用一些预先定义的按键来移动光标、删除文字、复制或粘贴文字等。这些按键均是普通的字符,例如 l 是向右移动光标,相当于向右箭头键,k 是向下移动光标,相当于向下箭头键。在编辑模式下,用户还可以利用一些特殊按键选定文字,然后再进行删除、或复制等操作。 当用户在编辑模式下键入 i, a, o 等命令之后,可进入插入模式;键入 : 可进入命名模式。在插入模式下,用户随后输入的,除 Esc 之外的任何字符均将被看成是插入到编辑缓冲区中的字符。按 Esc 之后,从插入模式切换到编辑模式。 在命令模式,Vi 将把光标挪到屏幕的最下方,并在第一个字符的位置显示一个 :(冒号)。这时,用户就可以键入一些命令。这些命令可用来保存文件、读取文件内容、执行 Shell 命令、设置 Vi 参数、以正则表达式的方式查找字符串或替换字符串等。 1.6.2?编辑模式 1. 移动光标 要对正文内容进行修改,首先必须把光标移动到指定位置。移动光标的最简单的方式是按键盘的上、下、左、 右箭头键。除了这种最原始的方法之外,用户还可以利用 vi 提供的众多字符组合键,在正文中移动光标,迅 速到达指定的行或列,实现定位。例如: k、j、h、l???功能分别等同于上、下、左、右箭头键 Ctrl+b?????在文件中向上移动一页(相当于 PageUp 键) Ctrl+f?????在文件中向下移动一页(相当于 PageDown 键) H??????? 将光标移到屏幕的最上行(Highest) nH???????将光标移到屏幕的第 n 行 2H???????将光标移到屏幕的第 2 行 M??????? 将光标移到屏幕的中间(Middle) L??????? 将光标移到屏幕的最下行(Lowest) nL???????将光标移到屏幕的倒数第 n 行 3L???????将光标移到屏幕的倒数第 3 行 w??????? 在指定行内右移光标,到下一个字的开头 e??????? 在指定行内右移光标,到一个字的末尾 b??????? 在指定行内左移光标,到前一个字的开头 0??????? 数字0,左移光标,到本行的开头 $??????? 右移光标,到本行的末尾 ^??????? 移动光标,到本行的第一个非空字符 2. 替换和删除 将光标定位于文件内指定位置后,可以用其他字符来替换光标所指向的字符,或从当前光标位置删除一个或多 个字符。例如: rc???????用 c 替换光标所指向的当前字符 nrc?????? 用 c 替换光标所指向的前 n 个字符 5rc?????? 用 c 替换光标所指向的前 5 个字符 x??????? 删除光标所指向的当前字符 nx???????删除光标所指向的前 n 个字符 3x???????删除光标所指向的前 3 个字符 dw???????删除光标右侧的字 ndw?????? 删除光标右侧的 n 个字 3dw?????? 删除光标右侧的 3 个字 db???????删除光标左侧的字 ndb?????? 删除光标左侧的 n 个字 5db?????? 删除光标左侧的 5 个字 dd???????删除光标所在行,并去除空隙 ndd?????? 删除 n 行内容,并去除空隙 3dd?????? 删除 3 行内容,并去除空隙 3. 粘贴和复制 从正文中删除的内容(如字符、字或行)并没有真正丢失,而是被剪切并复制到了一个内存缓冲区中。用户可 将其粘贴到正文中的指定位置。完成这一操作的命令是: p??????? 小写字母 p,将缓冲区的内容粘贴到光标的后面 P??????? 大写字母 P,将缓冲区的内容粘贴到光标的前面 如果缓冲区的内容是字符或字,直接粘贴在光标的前面或后面;如果缓冲区的内容为整行正文,则粘贴在当前 光标所在行的上一行或下一行。 注意上述两个命令中字母的大小写。vi 编辑器经常以一对大、小写字母(如 p 和 P)来提供一对相似的功能 。通常,小写命令在光标的后面进行操作,大写命令在光标的前面进行操作。 有时需要复制一段正文到新位置,同时保留原有位置的内容。这种情况下,首先应当把指定内容复制(而不是 剪切)到内存缓冲区。完成这一操作的命令是: yy???????复制当前行到内存缓冲区 nyy?????? 复制 n 行内容到内存缓冲区 5yy?????? 复制 5 行内容到内存缓冲区 4. 搜索字符串 和许多先进的编辑器一样,vi 提供了强大的字符串搜索功能。要查找文件中指定字或短语出现的位置,可以 用 vi 直接进行搜索,而不必以手工方式进行。搜索方法是:键入字符 / ,后面跟以要搜索的字符串,然后 按回车键。编辑程序执行正向搜索(即朝文件末尾方向),并在找到指定字符串后,将光标停到该字符串的 开头;键入 n 命令可以继续执行搜索,找出这一字符串下次出现的位置。用字符 ? 取代 / ,可以实现反向 搜索(朝文件开头方向)。例如: /str1????? 正向搜索字符串 str1 n??????? 继续搜索,找出 str1 字符串下次出现的位置 ?str2????? 反向搜索字符串 str2 无论搜索方向如何,当到达文件末尾或开头时,搜索工作会循环到文件的另一端并继续执行。 5. 撤销和重复 在编辑文档的过程中,为消除某个错误的编辑命令造成的后果,可以用撤消命令。另外,如果用户希望在新 的光标位置重复前面执行过的编辑命令,可用重复命令。 u??????? 撤消前一条命令的结果 .??????? 重复最后一条修改正文的命令 6. 文本选中 vi 可进入到一种成为 Visual 的模式,在该模式下,用户可以用光标移动命令可视地选择文本,然后再执行其他编辑操作,例如删除、复制等。 v 字符选中命令 V 行选中命令 #DEMO# 1.6.3?插入模式 1. 进入插入模式 在编辑模式下正确定位光标之后,可用以下命令切换到插入模式: i??????? 在光标左侧输入正文 a??????? 在光标右侧输入正文 o??????? 在光标所在行的下一行增添新行 O??????? 在光标所在行的上一行增添新行 I??????? 在光标所在行的开头输入正文 A??????? 在光标所在行的末尾输入正文 上面介绍了几种切换到插入模式的简单方法。另外还有一些命令,它们允许在进入插入模式之前首先删去一段 正文,从而实现正文的替换。这些命令包括: s??????? 用输入的正文替换光标所指向的字符 ns???????用输入的正文替换光标右侧 n 个字符 cw???????用输入的正文替换光标右侧的字 ncw?????? 用输入的正文替换光标右侧的 n 个字 cb???????用输入的正文替换光标左侧的字 ncb?????? 用输入的正文替换光标左侧的 n 个字 cd???????用输入的正文替换光标的所在行 ncd?????? 用输入的正文替换光标下面的 n 行 c$???????用输入的正文替换从光标开始到本行末尾的所有字符 c0???????用输入的正文替换从本行开头到光标的所有字符 2. 退出插入模式 退出插入模式的方法是,按 ESC 键或组合键Ctrl+[ 。 #DEMO# 1.6.4?命令模式 在 vi 的命令模式下,可以使用复杂的命令。在编辑模式下键入“:”,光标就跳到屏幕最后一行,并在那里显示冒号,此时已进入命令模式。命令模式又称“末行模式”,用户输入的内容均显示在屏幕的最后一行,按回车键,vi 执行命令。 1. 退出命令 在编辑模式下可以用 ZZ 命令退出 vi 编辑程序,该命令保存对正文所作的修改,覆盖原始文件。如果只需要 退出编辑程序,而不打算保存编辑的内容,可用下面的命令: : q?????? 在未作修改的情况下退出 : q!??????放弃所有修改,退出编辑程序 2. 行号与文件 编辑中的每一行正文都有自己的行号,用下列命令可以移动光标到指定行: : n?????? 将光标移到第 n 行 命令模式下,可以规定命令操作的行号范围。数值用来指定绝对行号;字符“.”表示光标所在行的行号;字符 符“$”表示正文最后一行的行号;简单的表达式,例如“.+5”表示当前行往下的第 5 行。例如: :345????????将光标移到第 345 行 :345w file???将第 345 行写入 file 文件 :3,5w file???将第 3 行至第 5 行写入 file 文件 :1,.w file???将第 1 行至当前行写入 file 文件 :.,$w file???将当前行至最后一行写入 file 文件 :.,.+5w file????从当前行开始将 6 行内容写入 file 文件 :1,$w file???将所有内容写入 file 文件,相当于 :w file 命令 在命令模式下,允许从文件中读取正文,或将正文写入文件。例如: :w???????将编辑的内容写入原始文件,用来保存编辑的中间结果 :wq?????? 将编辑的内容写入原始文件并退出编辑程序(相当于 ZZ 命令) :w file???? 将编辑的内容写入 file 文件,保持原有文件的内容不变 :a,bw file???将第 a 行至第 b 行的内容写入 file 文件 :r file???? 读取 file 文件的内容,插入当前光标所在行的后面 :e file???? 编辑新文件 file 代替原有内容 :f file???? 将当前文件重命名为 file :f???????打印当前文件名称和状态,如文件的行数、光标所在的行号等 3. 字符串搜索 给出一个字符串,可以通过搜索该字符串到达指定行。如果希望进行正向搜索,将待搜索的字符串置于两个“ /”之间;如果希望反向搜索,则将字符串放在两个“?”之间。例如: :/str/???????????正向搜索,将光标移到下一个包含字符串 str 的行 :?str????????????反向搜索,将光标移到上一个包含字符串 str 的行 :/str/w file????????正向搜索,并将第一个包含字符串 str 的行写入 file 文件 :/str1/,/str2/w file????正向搜索,并将包含字符串 str1 的行至包含字符串 str2 的行写 ????????????? 入 file 文件 4. 正文替换 利用 :s 命令可以实现字符串的替换。具体的用法包括: :s/str1/str2/??? 用字符串 str2 替换行中首次出现的字符串 str1 :s/str1/str2/g???用字符串 str2 替换行中所有出现的字符串 str1 :.,$ s/str1/str2/g?用字符串 str2 替换正文当前行到末尾所有出现的字符串 str1 :1,$ s/str1/str2/g?用字符串 str2 替换正文中所有出现的字符串 str1 :g/str1/s//str2/g? 功能同上 从上述替换命令可以看到:g 放在命令末尾,表示对搜索字符串的每次出现进行替换;不加 g,表示只对搜索 字符串的首次出现进行替换;g 放在命令开头,表示对正文中所有包含搜索字符串的行进行替换操作。 5. 删除正文 在命令模式下,同样可以删除正文中的内容。例如: :d?????????删除光标所在行 :3d???????? 删除 3 行 :.,$d??????? 删除当前行至正文的末尾 :/str1/,/str2/d?? 删除从字符串 str1 到 str2 的所有行 6. 恢复文件 vi 在编辑某个文件时,会另外生成一个临时文件,这个文件的名称通常以 . 开头,并以 .swp 结尾。vi 在 正常退出时,该文件被删除,若意外退出,而没有保存文件的最新修改内容,则可以使用恢复命令: :recover????? 恢复文件 也可以在启动 vi 时利用 -r 选项。 #DEMO# #DEMO# 1.6.5?选项设置 为控制不同的编辑功能,vi 提供了很多内部选项。利用 :set 命令可以设置选项。基本语法为: :set option???? 设置选项 option 常见的功能选项包括: autoindent?????设置该选项,则正文自动缩进 ignorecase?????设置该选项,则忽略规则表达式中大小写字母的区别 number???????设置该选项,则显示正文行号 ruler??????? 设置该选项,则在屏幕底部显示光标所在行、列的位置 tabstop?????? 设置按 Tab 键跳过的空格数。例如 :set tabstop=n,n 默认值为 8 mk?????????将选项保存在当前目录的 .exrc 文件中 #DEMO# 1.6.6?shell 切换 在编辑正文时,利用 vi 命令模式下提供的 shell 切换命令,无须退出 vi 即可执行 Linux 命令,十分 方便。语法格式为: :! command?????执行完 shell 命令 command 后回到 vi 另外,在编辑模式下,键入 K ,可命令 vi 查找光标所在单词的手册页,相当于运行 man命令。 #DEMO# 1.6.7?vim 和 gvim 的高级特色 Vim 代表 Vi IMproved,如同其名称所暗示的那样,Vim 作为标准 UNIX 系统 vi 编辑器的提高版而存在。 Vim 除提供和 vi 编辑器一样强大的功能外,还提供有多级恢复、命令行历史以及命令及文件名补全等功能。 gvim 是 vi 的 X Window 版本,该版本支持鼠标选中,一些高级光标移动功能,并且带有菜单和工具按钮。 #DEMO#另一篇优秀的教程 =======================================vi 命令常见问题解答作者:译者Elale[vi-faq中文版]0.0 - 引言 -- 我怎样用这个FAQ这个文档分为了几个部分.首先,第0节和第1节介绍了什么是vi;第2节则收录了很多新学者的问题,一些对vi没有很多经验的人也经常问这些问题.这里面包括诸如“命令模式和插入模式之间的区别”,以及“我怎样拷贝和粘贴”之类的问题.第3节是面向vi的中级用户的,它从问题“我如何查找和替换”开始,逐步深入,直到对vi里面的宏(Macro)的用法讨论为止.第3节还包括了一个vi的快速参考,有一个规范的vi命令列表.再下面,是一个有关“:set”命令的我们已经在一个运行SunOS和UCB版本vi的机器上验证了快速参考.除了SunOS带的vi外,每个命令都可以在系统V和UCB版本vi运行,但是我个人并没有验证这一点.除非我们在文档中指明,缺省我们假定你处在命令模式下.我们还尝试保留尽可能多的术语,因为在原始的vi文档中使用了这些术语,尽管我可能忘了它的本来含义.0.1 - 索引第一个文件:0.0 - 引言 -- 我怎样用这个FAQ?0.1 - 索引0.2 - 我可以散发这个FAQ吗?0.3 - 你能为这个FAQ做什么?1.0 - 什么是vi?1.1 - 关于vi有什么重大的交易吗? 为什么大家都用它? 更进一步说,为什么我要用它?1.2 - 噢! 这听起来不错! 有没有理由不用vi?1.3 - vi能在多少不同的操作系统下面运行?1.4 - 好吧, 你说服了我. 我决定开始使用vi. 我该从哪儿开始?1.5 - vi有其他一些可用的变种吗?2.0 - vi入门2.1 - 有什么游戏帮助我们学习vi吗?2.2 - 命令模式和插入模式有什么区别?2.3 - 等等,我的键盘没有<Esc>键,我该怎么办?2.4 - 那些~s是什么东西?2.5 - 我无法习惯用 hjkl, 你有什么建议吗?2.6 - 我如何才能不存盘就退出?2.7 - 我怎样插入一个文件?2.8 - 我怎样查找文本?2.9 - 我怎样搜索一个控制序列?2.10 - 我怎样重新格式化文本?2.11 - 我怎样复制文本?2.12 - 啊! 我刚才敲了一个dG,然后我的论文就没有了! 我该怎么办?(或者,我刚才犯了个错误,我该怎么办?)2.13 - 我正在写我的论文,被告知我必须将每一节都放在不同的文件里,我该怎么办?2.14 - 所有的:命令都是怎样处理的?3.0 - 怎样查找和替换?3.1 - 我怎样在vi中运行一个程序?3.2 - 啊! 我正在写我的论文, 系统崩溃了! 怎么办?3.3 - 有没有使vi对程序员更友好的窍门?3.4 - 宏 -- 我怎样写宏?3.5 - 我怎样将一个功能键定义成一个宏?3.6 - 有没有办法缩写文本?3.7 - 我怎样在当前文档中做拼写检查?3.8 - 我手头有一个硬拷贝的终端, 我还能用vi吗?3.9 - 好了,是不是处在开放模式下的原因呀?! 但是我现在没有用硬拷贝终端,它还是在开放模式呀?第二个文件:4.0 - vi档案的在线帮助在哪儿?5.0 - 好玩的vi诀窍,无聊的宏5.1 - 好玩的vi诀窍5.2 - 好玩的宏6.0 - 依字母顺序的vi快速参考6.1 - 命令模式的输入选项(:命令)6.2 - 设置选项(set)7.0 - 建立 .exrc文件7.1 - .exrc文件的样本8.0 - vi的漏洞9.0 - 术语表10.0 - 关于vi的参考书目0.2 - 我可以散发这个FAQ吗?可以!只要你没有对它做任何修改,或者用它来赚钱.0.3 - 你能为这个FAQ做什么?首先, 把你发现的错误告诉我. 如果你有什么建议我们也很欢迎. 你认为还不清楚的地方告诉我们,我们同样欢迎.还有, 使用vi! (Spread the word) 我很抱歉我无法将所有对这个FAQ有贡献的人都列出来, 因为许许多多的人都给过我建议和帮助,如果我将他们都列出来的话,那么恐怕这张贡献者的清单将和这个文档本身一样长了.1.0 - 什么是vi?vi是个可视化的编辑器(vi就意味着可视化--VIsual). 那么,什么是可视化的编辑器呢?(相对于非可视化的编辑器来说)?可视化的编辑器就是可以让你在编辑文本的时候看到它们.今天,这听起来似乎非常普通,反之,非可视化的编辑器似乎很奇怪. 非可视化的编辑器的例子可以举出不少:如ed, sed和edlin(直到相当近的一段时间内,它是DOS自带的最后一个编辑器)等.vi是威廉.侨伊写的,作为BSD UNIX的一部分. 后来AT&T也开始用vi, 于是标准UNIX也开始用vi了.1.1 - 关于vi有什么重大的交易吗? 为什么大家都用它? 更进一步说,为什么我要用它?vi是UNIX下面的缺省编辑器, 因此几乎近来所有的UNIX都捆绑了vi(近来是指1984年左右).这意味着无论何时你跨平台使用某种UNIX,你都知道在你指尖下面有一个强力的编辑器.为什么不是别的呢? vi是个强大的编辑器.同样,一旦你了解了vi,你就能很快的编辑你的文件,因为它非常能节省你的敲键次数. 由于它在插入和命令两种情况下使用不同的模式,它比大多数的不基于这种模式的编辑器要快. 而且,vi非常小(我机器上面的版本只有200K).还有,vi几乎能做任何事,只要你知道如何使它做你想做的事.1.2 - 噢! 这听起来不错! 有没有理由不用vi?有. 有一个非常好的理由: vi稍微有些难学, 如果你开始学的话,vi又慢又让人痛苦,当然,一旦你学会了, vi就快多了. 但是学习的过程很慢. 有人曾经问我, 如果vi是个比较易学的编辑器, 它是否直观(intuitive)呢? 我一般这样回答:"是的,我们有些人是这样认为.但是大多数人认为我们疯了."1.3 - vi能在多少不同的操作系统下面运行?UNIX. 就是它. 尽管如此,还是有很多vi的变种运行在不同的操作系统上. 我就在以下一些操作系统上用过vi: UNIX, DOS, OS/2, MAC SYSTEM 7.(后面有一个有关细节的列表)1.4 - 好吧, 你说服了我. 我决定开始使用vi. 我该从哪儿开始?好吧, 狡猾的家伙. 关于vi有很多很好的书:大多数讲UNIX的书至少有一章给了vi,而且有不少是专门讲vi的书.我没有什么偏爱. 所以你最好是问问你们那儿的vi高手们他们是从哪儿学来的. 还有,到处试. 用vi打开一个不重要的文档(你的论文不象是个学vi的好实验品),然后再到处试. 我无法想象有人学习vi却不花相当多的时间去到处试试. 记住:如果你有些地方不明白了, 只要敲两次<Esc>键,你就又回到命令模式下了.我要提到的一点是,我想在这里提比较合适,就是如果要成为系统管理员或者其他对UNIX配置做什么修改的话,最好是学学ed或者ex,因为有些版本的UNIX没有把vi放在根分区里面,这样你就可能无计可施了. ed是个不错的选择.1.5 - vi有其他一些可用的变种吗?只能列出一部分:STvi (STevie), elvis, vile, vim, 和nvi, xvi.elvis适用于:Amiga, DOS, OS/2, Unix, VMS, Atari.STevie适用于: Atari ST, DOS, Unix, Mac System 7.Mac System 7可以在很多info-mac的镜象站点获取,在/info-mac/text下.(例如ftp.hawaii.edu)nvi是将和BSD 4.4捆绑在一起的vi.vim适用于: Amiga, DOS, Mac System 7, Unix.Amiga, DOS,和源码可以在以下站点换取:ftp.fu-berlin.de /misc/editors/vimMac System 7可以在很多info-mac的镜象站点获取,在/info-mac/text下.(例如ftp.hawaii.edu)vile适用于: DOS, OS/2, Unix, VMS.xvi适用于: DOS, Unix.vi的变种之间很有很多差异.很多都改进了vi,大多数都可以使用在这个文档种列出的命令,但是有一些不同的地方.更进一步的细节,你可以参考这些变种附带的相应的文档.2.0 - vi入门对vi的初学者来说,有些基本的提示.第一,任何时候,手头都要有一份命令摘要.我们将在后面给出一个快速参考/命令摘要. 第二, 找一本vi方面的比较好的书.这个文档不是学vi的最佳途径(最起码现在还不是),我不敢保证这个文档能教会一个对vi一无所知的人, 而很多书已经做到了这一点. 但是,我们这里还是给出了不少提示. 对选择书籍来说,有一个标准的原则:买之前一定要仔细阅读. 要了解这本书对你是否有意义.确信它能在你练习vi的时候有用. 和其他的书做个比较 -- 不管怎样,vi可能让你感到非常莫名其妙, 而且你要确信这么一点:是书让你糊涂,而不是你低估了学vi的难度.还有, 找一些诸如"学vi"(vilearn),"vi向导"(vitutor)之类的软件来帮助你掌握vi的基本知识.2.1 - 有什么游戏帮助我们学习vi吗?这似乎很无聊, 但是事实上UNIX系统里面有不少游戏可以帮助你学习使用vi.这些帮助主要是一些基本知识. 虽然我还不知道有哪个游戏可以帮你学习vi的所有命令, 但我确实知道有一些可以帮助你学习使用 hjkl来移动光标. NetHack,一个类Rogue的游戏,就对这非常有帮助. 而且它是一个很大的游戏,能玩很长一段时间. 我没有贬低其他游戏的意思,这些游戏是: rogue, moria, omega, worm, snake.2.2 - 命令模式和插入模式有什么区别?vi将命令模式和插入模式区分开来,这经常被认为是vi的一个大问题,但往往这也被认为是vi的优势所在. 理解其中的区别是掌握vi的关键.vi启动时,开始处于命令模式;在这种模式下,我们可以在文件中到处移动,改变文本的某个特定区域, 剪切, 复制和粘贴文本,还有更多. 插入模式是指用户可以真正插入文本.换句话说,命令模式是用来在文件中移动,而插入模式是用来在文件中键入文本.有些命令,例如: a, i, c, C, O, o和其他一些可以从命令模式切换到插入模式.<Esc>键或者^C(CRTL+C)可以脱离插入模式而返回到命令模式.你要适应这种差别. 它使得vi区别于其他的编辑器. 它也使你能在你的手不离开标准键盘做很多事情.2.3 - 等等,我的键盘没有<Esc>键,我该怎么办?试试敲 ^[(CTRL+[). 如果你的键盘有一个<Meta>键,再试试它.如果还不行,再试试^3.2.4 - 那些~s是什么东西?它们仅仅是用来让你知道你的文档末尾在哪儿.实际上它们并不在你的文档里面,所以你用不着担心它们.2.5 - 我无法习惯用 hjkl, 你有什么建议吗?首先,如果你的终端设置正确而且你连接的也没有问题的话,你可以使用箭头键.但是,如果你认为你要经常使用vi,那么最好是习惯使用 hjkl,因为它们敲起来更快. 而且,有时候连接出问题了,使得ESC序列都可能丢失了.(这样你可能就无法使用箭头键了--译注)2.6 - 我如何才能不存盘就退出?:q!可以做到这一点. 如果vi看起来冻住了,确信你没有错敲了个 ^S. 敲^Q可以解开^S.2.7 - 我怎样插入一个文件?:r <文件名>例如,要插入文件/etc/motd, 可以敲 :r /etc/motd.这将把文件插入到光标处.如果你在r前面指定了一个数字,那么这条命令将把文件插入到那个位置.2.8 - 我怎样查找文本?/<文本>将向前查找, ?<文本>将向后查找. ??或者//将重复上次查找. 在UNIX下,这已经是个可爱的标准用法了. 而且, 在vi中, n将查找文本下一次的出现位置. N重复上次查找,不过逆转了查找的方向. 在查找中可以使用规范式.2.9 - 我怎样搜索一个控制序列?/^V^<序列>^V会告诉vi照字面理解下一个字符,不要把它看作是一条命令.2.10 - 我怎样重新格式化文本?如果你的计算机有一个名叫fmt的程序, 你要做的仅仅是在命令模式下面敲!}fmt(记住,不要在前面加icon_smile.gif. 这可以重新格式化你的文件,从光标所在的位置一直到当前段落的结尾.如果你的机器里面没有fmt这个程序, 你就得去找个类似的软件了(我记得在公共域里面有不少这样的程序,但是我对此了解不多)2.11 - 我怎样复制文本?这有点复杂.把这节拿出来,多看几遍;还有,一定要多做实验."<字母>yy可以把一行文本拷贝到寄存器中(这里的寄存器是vi的术语,指可以存放剪切和拷贝下来的东西的地方), <字母>里面的字母必须是a到z之间的一个. "<字母>dd可以把一行剪切下来放到寄存器里面. 你可以在yy或者dd前面用数字指明要拷贝或者剪切的行数.如果<字母>中的字母是大写的话,意味着把文本插入到寄存器中已有的文本之前."<字母>p把文本插入到光标之后,"<字母>P把文本插入到光标之前.如果寄存器中含有某一行的开头或结尾,这一行将会被放到另一合适的行上. Y是yy的快捷方式. 还有, y$, yH,yM,等等,都是可以用的.d命令也是一样的.如果要快速的剪切和粘贴, 你就无须指定寄存器了.如果这样的话,你就不能往寄存器里面添加文本了.而且只要有一个删除命令的话,寄存器中的东西就没有了(包括x命令).举例来说,如果要移动上一段的话,你可以把光标移到段落的开头,敲"a13dd,再把光标移到你想要放文本的地方,敲"ap,就可以把那段文本放到光标所在的行后面.现在,大概你想要剪切和粘贴文本到不是行末尾的区域去.我们来看如何做到这一点:我们可以使用 m<字母> 命令来标记一个区域,这个字母可以和剪切/粘贴寄存器的字母相同,因为它们是保存在内存中的不同位置. 然后,敲"<寄存器>`<字母>[yy或者dd], 这里的寄存器就是要保存文本的那个寄存器,<字母>是用来标记的,yy和dd是你的操作.2.12 - 啊! 我刚才敲了一个dG,然后我的论文就没有了! 我该怎么办?(或者,我刚才犯了个错误,我该怎么办?)u可以撤消你刚才的操作.U可以撤消你对当前行的修改(当然,一行对于一篇论文来说当然很不够了). :e!可以不保存修改而重新把你的文件调进来. 还有,你删除的文本都保存在从0到9编号的寄存器里.所以,"<n>p就可以把上第n次的删除文本粘贴出来.你可以按如下的方法迅速地查看所有删除的文本. 先试一个,不对的话,敲u,再试下一个.(为加速这个过程,这时vi中的.命令和通常的用法不一样了.它不是重复上次操作,而是试下一个寄存器,这样你要做的无非就是: "1p u . u .,直到你撤消了你想撤消的删除操作)2.13 - 我正在写我的论文,被告知我必须将每一节都放在不同的文件里,我该怎么办?:[m],[n]w <文件名>可以将从第m行到第n行之间的文本保存到<文件名>所指定的文件中.这种行序号方法几乎在所有的:命令下都可以使用. 如果你用命令:[m],[n] w >><文件名>,这些文本将添加到文件的后面.2.14 - 所有的:命令都是怎样处理的?:后面的命令都是从ex编辑器里面过来的. 这就给vi加入了很多灵活性,也使vi功能更强大. 例如, 有很多的方法可以用来查找和替换,它们有很多的类似地方(事实上,它们在某种意义上说都是一样的)3.0 - 怎样查找和替换?有很多方法. 最简单的是::s/old/new/g, 但是,这仅对当前行起作用..., 所以,我们用:%s/old/new/g, 更一般的,我们还可以用:[范围]s/old/new/[cg],这里,[范围]是任意的行范围,包括行号,$(文件末尾),.(当前行),%(当前文件),或者两个行号之间加个破折号(或者可以这样: .,+5,这表示下面5行).[cgi]是c,g,i中间的一个或者什么也没有.c告诉vi每次替换的时候要给提示,g是说对所有一行中出现的地方都做替换.i则是指在查找时不区分大小写.如果最后一个斜杠(/)后面没有东西的话,那么vi只替换在行中第一次匹配的地方.我比较喜欢这样做::g/foobar/s/bar/baz/g, 这个命令首先搜寻foobar,然后把它变成foobaz. 它没有改变jailbars, 而其他的一些命令可能会改变jailbars. 这是我的方法,但是可能比较难记.当然,你还可以在查找的的时候使用正规式,以及在替换文本的时候使用其他一些命令.如果你在正规式里用(和)来剥离一个序列的话,你会发现你可以做很多好玩的事情.例如::g/(foo)(bar)/s/2/1baz/g 将foobar替换成foobaz还有一些特殊的序列:& 所有查找时匹配到的东西[1-9] 1到9号用(和)括起来的东西u 下一个字符将被变成大写.U 以后的字符都变成大写,直到遇到e或El 下一个字符将被变成小写.L 以后的字符都变成大写,直到遇到e或E[Ee] 更改大小写的选择区域的终点3.1 - 我怎样在vi中运行一个程序?:!命令 可以在vi中运行程序. :sh会启动一个交互式的外壳(SHELL).在这个外壳里面, 如果你愿意,你还可以再次运行vi. 当你在编辑Makefiles和配置文件来编译某个程序的时候,这可能比较有用. 这比:e优越之处在于它无须保存文件,而且如果你退出外壳的时候,vi还回到原来的地方.(当然,我还是建议你先保存一下文件)3.2 - 啊! 我正在写我的论文, 系统崩溃了! 怎么办?不要怕! 你会收到一封电子邮件,里面就是你的论文.敲入vi -r <文件名>(这个文件名就是系统崩溃时你正在编辑的文件)你就可以恢复出你的论文来.只敲vi -r将把所有可能恢复的文件都列出来.3.3 - 有没有使vi对程序员更友好的窍门?:set ai可以让vi自动对齐.:set sw=#,#是移动的宽度(shiftwidth),或者说TAB键的宽度(tabwidth);你可以用<<或者>>命令来左移或右移某一行. 还有, 你可以使用 <%或>%来将{,(或[等符号括起来的文本都左移或右移;这时候,你必须把光标放在这些符号({,(或[)上面.:set sm会在你敲},]或)显示出对应匹配的{,[或(来.:set lisp会对lisp编程有些帮助. ()被移到s表达式(s-expressions)外面,如果原子(atoms)没有停止则{}将被移走.3.4 - 宏 -- 我怎样写宏?:map <lhs> <rhs>, 其中<lhs>最多10个字符,<rhs>最多100个字符. 以后,如果你敲了<lhs>,vi就会用<rhs>来取代它.所有的宏都是在命令模式下开始的,但是可以在你想在的模式下终止. 记住,在你想用的控制字符前面加上^V.:unmap <lhs>将删除这个宏. :map!<lhs> <rhs> 使得<lhs>将<rhs>插入到文档中去.3.5 - 我怎样将一个功能键定义成一个宏?如果<lhs>是#n,n是0-9之间的一个数,那么这个宏就映射成某一个功能键了.(你可以试一下F1-F10之间的键--译者)3.6 - 有没有办法缩写文本?当然了. 这可是vi呀,它能做任何事情!:ab email ellidz@midway.uchicago.edu 可以在你敲完email后,把那个没有缩写的文本插入到文件中. :una email取消缩写.3.7 - 我怎样在当前文档中做拼写检查?这儿有一个宏可以做到这一点. 这些应该放在你的.exrc文件中(后面我们将对.exrc进一步讨论). 它是一个相当简单的宏. 它仅仅是调用ispell来处理当前文件.当然,你的系统里面一定得有ispell这个程序. 使用它的时候,只需要敲个V键就行了(因为vi并没有用V,所以V是一个比较合适的键)map V :w^M:!ispell % ^M:e!^M^M第二个^M使你在拼写检查完之后无须敲回车就可以到vi中.(译注, 在我的系统里,没有ispell,只有spell,我用它替换了ispell,工作的不错;还有,^M不是两个字符,而是一个字符,通过^V^M敲进去的;另外,我个人认为第二个^M还是不要的好,因为直接回到vi后你就无法看到拼写检查的结果了)3.8 - 我手头有一个硬拷贝的终端, 我还能用vi吗?好了,好了. 我并认为有人会真的问这个问题.这个问题太偏了,我们大可不必理它.(而且,它回答了一个非常普通的问题)vi启动的时候处于一种特殊的模式下面,叫做"开放模式"; 在这种状态下,事情或多或少的有些不同. 删除的字符在你面前显示成一些',vi会认为你的终端窗口只有一行. ^r可以把当前行重新输出. z则把当前行周围的窗口重画一遍.3.9 - 好了,是不是处在开放模式下的原因呀?! 但是我现在没有用硬拷贝终端,它还是在开放模式呀?这儿的问题就是vi没有认出你用的终端的类型. 于是它假定你有的是个最烂的终端,所以它决定依然处在开放模式下.这似乎没什么用处.因为没有多少人喜欢开放模式,但是开放模式还是需要知道你的终端的一些最起码的信息的.现在,我们来看如何解决这个问题.我们有可能把它分成几种特殊的情形,但是,一般情况下,这并没有用处. 如果你直到你的终端的类型, 你可以在UNIX提示符下面设置终端类型(在CSH及其变种下面,使用命令setenv TERM <终端类型>;在SH及其变种下面,使用命令TERM=<终端类型>;export TERM)最好你能把上面的命令写在.profile文件或者.cshrc文件里面,这样你一登录它就自动地给你设置好了.(当然,你应该知道如何使用ed,或者你能在UNIX提示符下面设置好终端类型以便能使用vi, 这样你才有可能去编辑这些文件)如果你确实不知道你地终端类型,试一试vt100.现在大多数地终端或者终端仿真器都能仿真vt100. 如果这还不能生效的话,你只好去找个高手来帮你了.4.0 - vi档案的在线帮助在哪儿?有一个vi的FAQ,其中列出了vi档案的所有在线文件. 同时它还列出了这些文档的镜象站点. 最主要的一个地址是alf.uib.no,但是这些文档在很多很多地地方都保存着. vi-archive faq把它们都给列出来了.你在下载这些文件之前一定要核对一下这个FAQ.因为很有可能有一个站点比去挪威的站点更近更快些.一个镜象站点是cs.uwp.edu/pub/vi, 另一个是monu6.cc.monash.edu.au/pub/Vi,这些站点上有很多有关vi的文件,还有一些vi的变种版本;当然,UCB版本的vi是肯定有的, 还有许多的宏.5.0 - 好玩的vi诀窍,好玩的宏这一节主要讲述一些无聊的诀窍和一些无聊的宏.事实上,任何vi的诀窍和宏我们都欢迎,只要它们不是过分冗长. 如果有人向我建议而我也认为确实值得加的话,我会考虑加进去的.5.1 - 好玩的vi诀窍xp 删除光标下的字符,再把粘贴到后面去.换句话说,它交换了当前两个字符的位置.ddp 和xp类似,不过是交换两行的位置.uu 撤消和重复上次所做的修改.(这可以使你不改变什么东西就可以到你上次所做的修改处)5.2 - 好玩的宏和垂直上方的字符交换位置map * kxjphxkP折行map g $80|F r(译注,我对这条宏表示疑问!)改变大多数单词的大小写map v ywmno:s/./~/g(译注,这条好象也不大对!)在当前的单词周围加上`和'map *` i`'在当前的单词周围加上'和'map *' i''在当前的单词周围加上"和"map *" i""(这几条也太无聊了吧--译注)在当前的单词周围加上``和``map! `` `'(咦,好象又有问题?--译注)从光标处把当前行分开,在下一行开头加上一个>号(例如,引用USENET).如果加上了单词的折行功能那么最后一个单词可能被折在第一行.map g may0O`ay$:s/./ /g(不对吧--译注)插入一个字符map g i$^[r6.0 - 依字母顺序的vi快速参考... 是指有些东西需要在命令之前或之后指明.这通常是说光标的移动键(h,j,k,l,w,b等等)或者是指行号.# (这里#代表一个数字) 执行n次后面的命令...: 进入ex模式) 下一句( 上一句} 下一段{ 上一段]] 下一节[[ 上一节0 行的开头$ 行的末尾^ 行的第一个非空白字符+ 下一行的开头- 上一行的开头(空格) 下一个字符(回车) 下一行/ 向前搜索? 向后搜索% 查找当前小(中,大)括号的匹配字符, 逆向重复上一个f,F,t或T操作; 重复上一个f,F,t或T操作. 重复上一个操作` 转到标记处' 转到标记所在行的开头`` 查找前回到上一个做标记的地方'' 查找前回到上一个做标记所在行的开头~ 切换字符的大小写" 保存到寄存器中!! 重复上一次SHELL命令! 把后面的文本送给命令, 取代输出(例如, !}fmt把当前的段落送给命令fmt处理,然后用fmt返回的东西替换输出.)>> 右移当前段落一个移动宽度(shiftwidth)<< 左移当前段落一个移动宽度(shiftwidth)>% 从当前到匹配小(中,大)括号之间的文本右移<% 从当前到匹配小(中,大)括号之间的文本左移(似乎漏了一个符号|, 移动到某一列----译注)a 在当前位置之后添加A 在当前行的末尾添加^a 没有使用b 上一个单词的开头B 上一个单词的开头,忽略标点符号^b 上移一屏c 覆盖...C 覆盖到行末尾^c 终止插入模式,在命令模式没有用d 删除...D 删除到行末尾^d 下移半屏,如果在插入模式下则移到上一个移动宽度(ShiftTab)处e 单词的末尾E 单词的末尾,忽略标点符号^e 屏幕下卷一行f 查找...F 向后查找...^f 下移一屏g 未用G ...跳至[缺省是到文件末尾]^g 显示状态栏h 左移H 屏幕上的第一行^h 在插入模式下是退格,命令模式下是左移i 在当前的位置前面插入I 在本行的第一个非空白字符前面插入^i 插入模式下是制表键,命令模式下未用j 下移J 把下一行合并到本行^j 命令模式下是下移,插入模式下是建一个新行k 上移K 未用^k 未用l 右移L 屏幕中的最后一行^l 重绘屏幕m 把当前位置标记到寄存器中M 屏幕的中间行^m 回车n 重复上次查找N 逆向重复上次查找^n 命令模式下是下移o 在当前行的下面建一个新行O 在当前行的上面建一个新行^o 未用p 在当前行的下面粘贴(译注--应为在当前位置的后面粘贴)P 在当前行的上面粘贴(译注--应为在当前位置的前面粘贴)^p 命令模式下是上移q 未用Q 退出并且启动ex^q 未用r 覆盖当前的字符R 在插入模式下一直覆盖字符^r 在命令模式下面重绘屏幕s 替换S 替换整行t 到...T 向后到...^t 移到下一个移动宽度(shifttab)处u 撤消上一次操作U 撤消对本行的所有修改^u 上移半屏v 未用V 未用^v 未用w 下一个单词的开头W 下一个单词的开头,忽略标点符号^w 命令模式下未用,在插入模式下是到上一个单词的开头处x 删除当前字符X 删除前一个字符^x 未用y 复制...Y 复制整行^y 屏幕上卷一行z 重新配置当前行周围的屏幕ZZ 保存之后退出^z 未用(译注--在命令模式下,^z执行了UNIX暂停操作)6.1 - 命令模式的输入选项(:命令)(注: 这不是一个规范的列表,, 我只是列出了一些最重要的命令):r <文件> 把<文件>读入到当前文档:r !<命令> 把<命令>的输出插入到当前文本中:nr <文件> 把<文件>插入到第n行:!<命令> 运行<命令>,然后返回:sh 转到SHELL:so <文件> 读取<文件>,再执行文件里面的命令(译注--文件中的命令应该都是一些ex命令)icon_mad.gif 保存之后退出:wq 保存之后退出:l1,l2w <文件>把第l1和第l2行之间的文本写到<文件>中去,如果没有指定<文件>,vi就假定是当前文件,如果没有指定l1,l2,就假定是整个文件(就成了:w):w >> <文件> 添加到<文件>末尾. 也可以使用行号:w! 覆盖当前文件:q 退出:q! 不存盘就退出:e <文件> 不离开vi编辑<文件>:e! 重新编辑当前文件,忽略所有的修改:n 编辑下一个文件:e +n <文件> 从第n行开始编辑<文件>,如果超过了末尾,就从末尾开始编辑:e# 编辑替换文件(如果使用了命令:e<文件>,替换文件就指的是原始文件):args 显示所有要编辑的文件:rew 重新回到第一个编辑的文档:map m n 创建一个宏(使 m 做 n):map! m n 创建一个插入模式的宏(使 m 做 n):unmap m 删除宏m:unmap! m 删除插入模式的宏m:ab <1> <2> 缩写,敲<1>的时候用<2>取代:unab <1> 取消缩写<1>:set <选项> 设置<选项>...6.2 - 设置选项(set)可以使用括号中的缩写形式. 语法::set <选项> <参数> (如果需要参数的话)也可以在一行中指定多个选项:set <选项>? 显示出当前这个选项的参数值:set all 则显示所有的选项值对那些无须参数的选项来说,使用:set no<选项>就可以把它给关了选项: 缺省值: 含义:autoindent (ai) noai 使新行自动缩进,和上(下)行的位置对齐autoprint (ap) ap 每条命令之后都显示出修改之处autowrite (aw) noaw 在:n,:!命令之前都自动保存文件beautify (bf) nobf 在输入的时候忽略所有的控制字符(除了制表键(tab),换行(newline),进纸(formfeed))directory= (dir=) /tmp 存放缓冲区的目录名edcompatible noedcompatible 在替换的时候使用类ed的用法errorbells (eb) errorbells 出错的时候响铃exrc (ex) noexrc 允许在主目录(home)外面之外放.exrc文件hardtabs= (ht=) 8 设置硬制表的边界ignore case (ic) noic 正规式里忽略大小写lisp nolisp 打开lisp模式list nolist 显示所有的制表键和行的结尾magic magic 可以使用更多的正规表达式mesg mesg 允许向终端发送消息number (nu) nonumber 显示行号open open 允许开放和可视化optimize (opt) optimize 优化吞吐量,打印时不发回车paragraphs= (para=) IPLPPPQPPLIbp 设置{ & }的分界符prompt prompt 命令模式下的输入给出:的提示符readonly (ro) noro 除非用!号否则不准保存文件redraw noredraw 当编辑的时候重绘屏幕remap remap 允许宏指向其他的宏report= 5 如果影响的行数>这个数的话就报告scroll 1/2 window 下卷屏幕时滚动屏幕的数目,同样这也是z命令输出的行数(z 输出2倍滚屏的大小)sections= SHNHH HU 定义节的末尾(当使用命令[[ 和 ]] 时)shell= (sh=) /bin/sh 缺省的SHELL,如果设置了环境变量SHELL的话,就使用变量shiftwidth= (sw=) 8 当使用移动(shift)命令时移动的字符数showmatch (sm) nosm 显示{, }, (, ), [, 或者 ] 的匹配情况showmode noshowmode 显示你处在什么模式下面slowopen (slow) 插入之后不要立刻更新显示tabstop= (ts=) 8 设置制表停止位(tabstop)的长度taglength= (tl=) 0 重要标记的字符个数(0表示所有的字符)tags= tag, /usr/lib/tags 定义包含标记的文件路径term= 设置终端类型terse noterse 显示简短的错误信息timeout (to) timeout 一秒钟后键盘映射超时ttytype= 设置终端类型warn warn 显示"No write since last change"信息window= (w=) 可视模式下窗口的行数wrapmargin= (wm=) 0 右边距,大于0的话最右边的单词将折行,留出n个空白位置wrapscan (ws) ws 查找到文件尾后再重头开始writeany (wa) nowa 可以保存到任意一个文件去(译注--这些选项在各种vi版本中都基本上大同小异,以SunOS带的vi为例,它没有这里列出来的open选项,scroll的参数值也不同,还多出来一些选项,如flash,modelines,novice,tagstack等等)7.0 - 建立 .exrc文件所有命令输入模式下的命令(即 :命令)都可以在.exrc文件中使用,在.exrc中的命令在启动vi的时候自动加载.尤其是源命令(so),缩写(ab)和宏定义都可以用.在.exrc中不允许有空行.以"开头的一行vi将把它当成注释.7.1 - .exrc文件的样本以下的.exrc文件是一个实际的例子, 我自己的. 因此,它就没有有些人想象的那样设置很多的选项.即便如此,它还是给出一些基本的概念,而且它也相当易懂.首先,记住你无须在命令前面加:号,因为它是缺省就添加了的."译注--以下是.exrc文件中的内容,为真实起见,而且事实上也相当浅显,我没有翻译其中的注释" set wordwrap 9 characters from the rightset wm=9" show matching parenthesis. When },), or ] is hit, show the opening" {,(, or [ that matches it.set sm" set the shell to be /usr/local/bin/tcshset sh=/usr/local/bin/tcsh" a few abbreviations" this makes -l automatically become -Larry, and zidlle to be my" name and email address.ab zidlle E. Larry Lidz - ellidz@midway.uchicago.eduab -l -Larry" uppercase V will run ispell -x (-x tells it not to save backups) on current" filemap V :w" K will center the line... (this doesn't work on SunOS -- ??)map K :s/^[ ]*//" v will reformat the current paragraphmap v {0!}fmt" q runs a program to lock my terminalmap q :!lock2" Splits a line in two at current cursor location, puts a > at the"beginning of the line - useful for Usenet/emailmap g may0O`ay$:s/./ /g8.0 - vi的bug我很想说vi中没有bug,但很不幸,它不是这样的. 这些bug都是初始版本vi中的,它其他的一些变种就不一定有.例如 _宏有时就运行的有问题.9.0 - 术语表如果有人提议说某个术语他不明白,我们将更新这个术语表.如果你有什么建议,请一定要告诉我.命令模式 command mode命令模式是说我们在此模式下面可以向vi发命令(包括光标移动,编辑命令等等)edUNIX里面一个非可视化的编辑器<Esc>escape键. 键盘上标记为escape(ESC)的一个键.有时候^[可以起到相同的作用.如果没有escape键,你可以试试Meta键exUNIX下的一个编辑器.所有vi中的:命令都是送给它处理的插入模式 insert mode插入模式是指我们可以在此模式下面键入文本.宏 macro宏是一些键的组合起来的快捷方式.例如,某个宏允许我们只敲一个键就可以执行好几个不同的命令.开放模式 open mode开始模式是说vi启动的时候不能确定你的终端类型,或者它肯定你的是一个硬的或电子管的终端正规表达式 regular expressions (RegEx)正规表达式,通常缩写为"RegEx",是一些关键字的集合,它允许用户在查找的时候有更大的控制力度. RegEx是在UNIX下面用的,但是在很多程序中也用到了它.sed流-行式的编辑器.它没有界面,所有命令都是通过命令行的形式给出的.vi就是这个FAQ讨论的编辑器按键功能图示: |