Linux上最常用的文本编辑器Vi

 

本章介绍 Linux 上最常用的文本编辑器 Vi 。文本编辑器是所有计算机系统中最常使用的一种工具。用户在使用计算机的时候,往往 需要 建立自己的文件,无论是一般的文本文件、数据文件,还是编写的源程序文件,这些 工作 都离不开编辑器。
   Linux 系统提供了一个完整的编辑器家族 系列 ,如 Ed Ex Vi Emacs 等,按 功能 它们可以分为两大类:行编辑器( Ed Ex )和全屏幕编辑器( Vi Emacs )。行编辑器每次只能对一行进行操作,使用起来很不方便。而全屏幕编辑器可以对整个屏幕进行编辑,用户编辑的文件直接显示在屏幕上,修改的结果可以立即看出来,克服了行编辑的那种不直观的操作方式,便于用户 学习 和使用,具有强大的功能。
   Vi Linux 系统的第一个全屏幕交互式编辑程序,它从诞生至今一直得到广大用户的青睐,历经数十年仍然是人们主要使用的文本编辑工具,足见其生命力之强,而强大的生命力是其强大的功能带来的。
  本章中,我们将循序渐进地介绍如何使用 Vi 来建立、编辑、显示以及处理文件。(注:文中的大写字母为[ shift ]键 相应的小写字母的组合)
    Vi 简介
   Vi “Visual interface” 的简称,它在 Linux 上的地位就仿佛 Edit 程序在 DOS 上一样。它可以执行输出、删除、查找、替换、块操作等众多文本操作,而且用户可以根据自己的需要对其进行定制,这是其他编辑程序所没有的。
   Vi 不是一个排版程序,它不象 Word WPS 那样可以对字体、格式、段落等其他属性进行编排,它只是一个文本编辑程序。
   Vi 没有菜单,只有命令,且命令繁多。 Vi 有三种基本工作模式:命令行模式、文本输入模式和末行模式。
  命令行模式
  任何时候,不管用户处于何种模式,只要按一下键, 即可 使 Vi 进入命令行模式;我们在 shell 环境(提示符为 $ )下输入启动 Vi 命令,进入编辑器时,也是处于该模式下。
  在该模式下,用户可以输入各种合法的 Vi 命令,用于管理自己的文档。此时从键盘上输入的任何字符都被当做编辑命令来解释,若输入的字符是合法的 Vi 命令,则 Vi 在接受用户命令之后完成相应的动作。但需注意的是,所输入的命令并不在屏幕上显示出来。若输入的字符不是 Vi 的合法命令, Vi 会响铃报警。
  文本输入模式
  在命令模式下输入插入命令 i 、附加命令 a 、打开命令 o 、修改命令 c 、取代命令 r 或替换命令 s 都可以进入文本输入模式。在该模式下,用户输入的任何字符都被 Vi 当做文件内容保存起来,并将其显示在屏幕上。在文本输入过程中,若想回到命令模式下,按键即可。
  末行模式
  末行模式也称 ex 转义模式。
   Vi Ex 编辑器的功能是相同的,二者主要区别是用户界面。在 Vi 中,命令通常是单个键,例如 i a o 等;而在 Ex 中,命令是以按回车键结束的正文行。 Vi 有一个专门的 转义 命令,可访问很多面向行的 Ex 命令。在命令模式下,用户按 “:” 键即可进入末行模式下,此时 Vi 会在显示窗口的最后一行(通常也是屏幕的最后一行)显示一个 “:” 作为末行模式的提示符,等待用户输入命令。多数文件管理命令都是在此模式下执行的(如把编辑缓冲区的内容写到文件中等)。末行命令执行完后, Vi 自动回到命令模式。例如:
   :1 $s / A / a / g
  则从文件第一行至文件尾将大写 A 全部替换成小写 a
  若在末行模式下输入命令过程中改变了主意,可按键,或用退格键将输入的命令全部删除之后,再按一下退格键,即可使 Vi 回到命令模式下。
   Vi 编辑器的三种工作模式之间的转换如图 11-1 所示
  如果要从命令模式转换到编辑模式,可以键入命令 a 或者 i ;如果需要从文本模式返回,则按 Esc 键即可。在命令模式下输入 “:” 即可切换到末行模式,然后输入命令。
  第二十五课 Vi 的进入与退出       2000 /6 /13
   Vi 的进入
  用户登录到系统中之后,系统给出提示符 “$” 。在提示符后键入 Vi 和想要编辑(或建立)的文件名,便可进入 Vi
  [例 1 键入命令:
   $ vi example.c
  屏幕显示如下:
   ~
   ~
   ~
   ~
   ~
   ~
   ~
   ~
   ~
   ~
   ~
   ~
   ~
   “ example.c” New File
  如果只键入 Vi ,而不带文件名,也可以进入 Vi 。之后在光标处键入文件内容,退出 Vi 时,只需在退出命令后输入文件名即可。
  进入 Vi 之后,首先进入的就是命令模式,也就是说等待命令输入而不是文本输入。这时输入的字母都将作为命令来解释。光标停在屏幕第一行首位上(用表示),其余各行行首均有一个 “~” 符号,表示该行为空行。最后一行也称状态行,显示出当前正在编辑的文件名以及其状态。如本例是[ New File ],表示 example.c 是一个新建的文件。如果 example.c 文件已在系统中存在,那么输入上述命令后,则在屏幕上显示出该文件的内容,并且光标停在第一行的首位,在状态行显示出该文件的文件名、行数和字符数。
  [例 2 键入命令:
   $ vi example.c
  然后键入:
   #include
   main
   { int k ;
   for k=0 ; k<3 ; k add ;
   }
   add
   { static int x=0;
   x ;
   printf “x = %d/n”, x ;
   }
   ~
   ~
   ~
   ~
   “ example.c” New File
  注意,在这里我们为了节省篇幅起见,屏幕只显示 15 行。事实上,初始的显示行数与用户所用 终端 有关,一般的 CRT 终端可显示 25 行。在窗口系统中,显示行数与运行 Vi 的那个窗口有关。然而我们可以对显示行数进行设置。例如,在能显示 25 行的 CRT 终端上,让 Vi 只显示 15 行。设置的方法将在本节后面介绍。
  当用 Vi 建立一个新文件时,在进入 Vi 的命令中也可以不给出文件名,当编辑完文件 需要 保存数据时,再由用户指定文件名。
  进入 Vi 时,用户不仅可以指定一个待编辑的文件名,而且还有许多附加操作。
  如果希望在进入 Vi 之后,光标处于文件中特定的某行上,可在 Vi 后加上任选项 n ,其中 n 为指定的行数。
  [例 3 键入命令:
   $ vi 5 example1.c
  后,屏幕显示如下:
   #include
   main
   { int k ;
   for k=0 ; k<3 ; k add ;
   }
   add
   { static int x=0;
   x ;
   printf “x = %d/n”, x ;
   }
   ~
   ~
   ~
   ~
   ~
   “ example.c” 12 lines, 125 characters
  光标将位于文件 example1.c 中的第 5 行上。
  如果希望在进入 Vi 之后光标处于文件最末行,则只需把命令中附加项 “ ” 后面的数字 n 省略掉即可。
  在进入 Vi 时,除了可以指定一个光标起始行号之外,还可以在命令中指定一个模式串,此时在进入 Vi 后,光标就处于文件中第一个与指定模式串相匹配的那行上。
  [例 4 键入命令:
   $ vi /int example1.c
  屏幕显示如下:
   #include
   main
   { int k ;
   for k=0 ; k<3 ; k add ;
   }
   add
   { static int x=0;
   x ;
   printf “x = %d/n”, x ;
   }
   ~
   ~
   ~
   ~
   ~
   “ example.c” 12 lines, 125 characters
  光标将位于文件 example1.c 中的第 3 行上。
  使用 Vi 可以同时编辑多个文件,只要在进入 Vi 的命令中写入所要操作的文件即可,还可以使用通配符。
  [例 5 键入命令:
   $ vi *.cat
  就可以编辑所有后缀为 cat 的文件了。当然,您还可以使用 shell 中内置的模式匹配来装载文件,这样会更富技巧性。一旦您在命令行中包含了所有的待编辑文件名,就可以在 Vi 中方便地移来移去。
  退出 Vi
  当编辑完文件,准备退出 Vi 返回到 shell 时,可以使用以下几种方法之一。
  在命令模式中,连按两次大写字母 Z ,若当前编辑的文件曾被修改过,则 Vi 保存该文件后退出,返回到 shell ;若当前编辑的文件没被修改过,则 Vi 直接退出 , 返回到 shell
  在末行模式下,输入命令 :w
   Vi 保存当前编辑文件,但并不退出,而是继续等待用户输入命令。在使用 w 命令时,可以再给编辑文件起一个新的文件名。
  [例 6
   :w newfile
  此时 Vi 将把当前文件的内容保存到指定的 newfile 中,而原有文件保持不变。若 newfile 是一个已存在的文件,则 Vi 在显示窗口的状态行给出提示信息:
   File exists use ! to override
  此时,若用户真的希望用文件的当前内容替换 newfile 中原有内容,可使用命令
   :w! newfile
  否则可 选择 另外的文件名来保存当前文件。
  在末行模式下,输入命令 :q
  系统退出 Vi 返回到 shell 。若在用此命令退出 Vi 时,编辑文件没有被保存,则 Vi 在显示窗口的最末行显示如下信息:
   No write since last change use ! to overrides
  提示用户该文件被修改后没有保存,然后 Vi 并不退出,继续等待用户命令。若用户就是不想保存被修改后的文件而要强行退出 Vi 时,可使用命令 :q!
   Vi 放弃所作修改而直接退到 shell 下。
  在末行模式下,输入命令 :wq
   Vi 将先保存文件,然后退出 Vi 返回到 shell 。在末行模式下,输入命令 :x
  该命令的功能同命令模式下的 ZZ 命令功能相同。
   Vi 中的行号
   Vi 中的许多命令都要用到行号及行数等数值。若编辑的文件较大时,自己去数是非常不方便的。为此 Vi 提供了给文本加行号的功能。这些行号显示在屏幕的左边,而相应行的内容则显示在行号之后。
  使用的命令为:在末行方式下输入命令:
   :set number
   需要 说明的是,这里加的行号只是显示给用户看的,它们并不是文件内容的一部分。
  在一个较大的文件中,用户可能需要了解光标当前行是哪一行,在文件中处于什么位置,可在命令模式下用组合键,此时 Vi 会在显示窗口的最后一行显示出相应信息。该命令可以在任何时候使用。
  [例 7
   #include
   main
   { int k ;
   for k=0 ; k<3 ; k add ;
   }
   add
   { static int x=0;
   x ;
   printf “x = %d/n”, x ;
   }
   ~
   ~
   ~
   ~
   ~
   “ example.c” Modified lines 4 of 10 --40%-- col 11
  在末行方式下,我们可以输入命令 nu (单词 number 的缩写)来 获得 光标当前行的行号与该行内容。
  光标移动操作
  全屏幕文本编辑器中,光标的移动操作无疑是最经常使用的操作了。用户只有熟练地使用移动光标的这些命令, 才能 迅速准确地到达所期望的位置处进行编辑。
   Vi 中的光标移动既可以在命令模式下,也可以在文本输入模式下,但操作的方法不尽相同。
  在文本输入模式下,可直接使用键盘上的四个方向键移动光标。
  在命令模式下,有很多移动光标的方法。不但可以使用四个方向键来移动光标,还可以用 h j k l 这四个键代替四个方向键来移动光标,这样可以避免由于不同机器上的不同键盘定义所带来的矛盾,而且使用熟练后可以手不离开字母键盘位置就能完成所有操作,从而提高 工作 效率。另外还可以用、、和四个键或组合键移动光标。且以上这三种键在实现功能上是等价的。除此之外,还有一些移动光标的命令。下面对它们的工作方式介绍如下:
  、 ® (均称为右向键)
  右向键的作用是将光标向右移动一个位置。若在向右键前先输入一个数字 n ,那么光标就向右移动 n 个位置。例如 5l 表示光标向右移动 5 个位置。需要注意的是,光标移动不能超过当前行的末尾。若给定的 n 超过光标当前位置至行尾的字符个数,如果用右向键,光标只能移到行尾;如果用,光标移到下面一行或几行的适当位置。
   h 、、 ¬ (向左键)
  执行一次向左键,光标向左移动一个位置。同向右键一样,也可以在向左键的前面输入一个数字 n ,那么光标就向左移动 n 个位置。需要注意的是,如果用左向键,光标左移不能超出该行的开头;如果用,光标移到上面一行或几行的适当位置。
   j 、、 ¯ (向下键)
  执行一次向下键光标向下移动一个位置(即一行),但光标所在的列不变。当这些命令前面加上数字 n ,则光标下移 n 行。
   Vi 除了可以用向下键将光标下移外,还可以用键和 “ ” 键将光标下移一行或 n 行(不包括本行在内),但此时光标下移之后将位于该行的第一个字符处。例如:
   3j 光标下移 3 行,且光标所在列的位置不变。
   3 3 光标下移 3 行,且光标位于该行的行首。
   k 、、 ­ (向上键)
  执行一次向上键光标向上移动一个位置(即一行),但光标所在的列不变。同样在这些命令前面加上数字 n ,则光标上移 n 行。
  若希望光标上移之后,光标位于该行的行首,则可以使用命令 “- ”
   L (移至行首)
   L 命令是将光标移到当前行的开头,即将光标移至当前行的第一个非空白处(非制表符或非空格符)。
   $ (移至行尾)
  该命令将光标移到当前行的行尾,停在最后一个字符上。若在 $ 命令之前加上一个数字 n ,则光标下移 n-1 行并到达行尾。
  [行号] G (移至指定行)
  该命令将光标移至指定行号所指定的行的行首。这种移动称为绝对定位移动。
  [例 8
   #include
   main
   { int k ;
   for k=0 ; k<3 ; k add ;
   }
   add
   { static int x=0;
   x ;
   printf “x = %d/n”, x ;
   }
   ~
   ~
   ~
   ~
   ~
   “ example.c” 12 lines, 125 characters
  键入命令 :6G 后,屏幕显示如下:
   #include
   main
   { int k ;
   for k=0 ; k<3 ; k add ;
   }
   add
   { static int x=0;
   x ;
   printf “x = %d/n”, x ;
   }
   ~
   ~
   ~
   ~
   ~
   “ example.c” 12 lines, 125 characters
  光标移到了第 6 行的行首。
  若省略行号,则光标移至该文件的最后一行的行首,即无论该文件有多少屏,都跳至最后一行。
  第二十七课 vi 命令   
  在屏幕上移动
   Vi 提供了三个关于光标在全屏幕上移动并且文件本身不发生滚动的命令。它们分别是 H M L 命令。
   1. H 命令
  该命令将光标移至屏幕首行的行首(即左上角),也就是当前屏幕的第一行,而不是整个文件的第一行。利用此命令可以 快速 将光标移至屏幕顶部。若在 H 命令之前加上数字 n ,则将光标移至第 n 行的行首。
  [例 9 屏幕显示如下内容:
   #include
   main
   { int k ;
   for k=0 ; k<3 ; k add ; }
   add
   { static int x=0;
   x ;
   printf “x=%d/n”, x ;
   }
   ~
   ~
   ~
   ~
   ~
   “ example.c” New File
  在命令模式下输入 4H 命令后,光标移到以 for 开头的这一行的字母 f 上。
  值得一提的是,使用命令 dH 将会删除从光标当前所在行至所显示屏幕首行的全部内容。
   2. M 命令
  该命令将光标移至屏幕显示文件的中间行的行首。即如果当前屏幕已经充满 , 则移动到整个屏幕的中间行;如果并未充满,则移动到文本的那些行的中间行。利用此命令可以快速地将光标从屏幕的任意位置移至屏幕显示文件的中间行的行首。例如,在上面屏幕显示的情况下(不论光标在屏幕的何处),在命令模式下,输入命令 M 之后,光标都将移到 add 这一行的字母 a 上。
  同样值得一提的是,使用命令 dM 将会删除从光标当前所在行至屏幕显示文件的中间行的全部内容。
   3. L 命令
  当文件显示内容超过一屏时,该命令将光标移至屏幕上的最底行的行首;当文件显示内容不足一屏时,该命令将光标移至文件的最后一行的行首。可见,利用此命令可以快速准确地将光标移至屏幕底部或文件的最后一行。若在 L 命令之前加上数字 n ,则将光标移至从屏幕底部算起第 n 行的行首。例如,在上面屏幕显示的情况下(不论光标在屏幕的何处),在命令模式下,输入命令 3L 之后,光标都将移到 x 这一行的字母 x 上。
  同样值得一提的是,使用命令 dL 将会删除从光标当前行至屏幕底行的全部内容。
  按字移动光标
  首先介绍一下 Vi 的概念。在 Vi 有两种含义。一种是广义的字,它可以是两个空格之间的任何内容。
  [例 10 在文件 example.c 中的第 4 行:
   {int k
  它只有 2 个字,一个是 {int ,另一个是 k;
   Vi 中另一种字是狭义上的字,在此种意义之下,英文单词、标点符号和非字母字符(如 ! @ # $ % ^ & * 、(、)、 - { } 、[、]、 ~ | / < > / 等)均被当成是一个字。因此,上面那一行中就包括 { int k 、;这 4 个字。
   Vi 中使用大写命令一般就是指将字作为广义来对待,使用小写命令就是作为狭义对待。
  搞清楚 Vi 中字的含义后,我们就可以介绍按字移动光标的命令了。
   Vi 一共提供了三组关于按字移动光标的命令,分别是:
   1. w W 命令
  将光标右移至下一个字的字首;
  [例 11 屏幕上显示如下:
   printf “Hello Mr.Huang!/n” ;
  现在使用 w 命令,把光标移到下一个字(狭义)的字首 上:
   printf “Hello Mr.Huang!/n” ;
  下面使用 W 命令,将把光标移到下一个字(广义)的字首 “M” 上:
   printf “Hello Mr.Huang!/n” ;
   2. e E 命令
  如果光标起始位置处于字内(即非字尾处),则该命令将把光标移到本字字尾;如果光标起始位置处于字尾,则该命令将把光标移动到下一个字的字尾。
   3. b B
  如果光标处于所在字内(即非字首),则该命令将把光标移至本字字首;如果光标处于所在字字首,则该命令将把光标移到上一个字的字首。
  [例 12 屏幕显示如下:
   printf “Hello Mr.Huang!/n” ;
  现在使用 b 命令,由于光标处于该字中间,所以光标移动到本字字首 “H” 处:
   printf “Hello Mr.Huang!/n” ;
  如果使用 B 命令,则如下所示:
   printf “Hello Mr.Huang!/n” ;
  按句移动光标
  在 Vi 中,一个句子被定义为是以逗号( , )、句号( . )、问号( ? )和感叹号( ! )结尾,且其后面跟着至少两个以上(含两个)空格或一个换行符的字符序列。
   Vi 提供了关于按句移动光标的两个命令,分别为:
   1. 命令
  将光标移 至上 一个句子的开头。
   2. 命令
  该命令将光标移至下一个句子的开头。
  按段移动光标
  在 Vi 中,一个段被定义为是以一个空白行开始和结束的片段。 Vi 提供了关于按段移动光标的两个命令,分别为:
   1. { 命令
  该命令将光标向前移至上一个段的开头;
   2. } 命令
  该命令将光标向后移至下一个段的开头。
  屏幕滚动
  屏幕命令是以屏幕为单位移动光标的,常用于文件的滚屏和分页。 需要 注意的是,屏幕命令不是光标移动命令,不能作为文本限定符用于删除命令中。
  在命令模式下和文本输入模式下均可以使用屏幕滚动命令。
   1. 滚屏命令
  关于滚屏命令有两个:
   · < Ctrl u > 将屏幕向前(文件头方向)翻滚半屏;
   · < Ctrl d > 将屏幕向后(文件尾方向)翻滚半屏。
  可以在这两个命令之前加上一个数字 n ,则屏幕向前或向后翻滚 n 行。并且这个值被系统记住,以后再用 < Ctrl u > < Ctrl d > 命令滚屏时,还滚相应的行数。
   2. 分页命令
  关于分页命令也有两个:
   · < Ctrl f > 将屏幕向文件尾方向翻滚一整屏(即一页);
   · < Ctrl b > 将屏幕向文件首方向翻滚一整屏(即一页)。
  同样也可以在这两个命令之前加上一个数字 n ,则屏幕向前或向后移动 n 页。
   3. 状态命令 < Ctrl G >
  命令显示在 vi 状态行上的 vi 状态信息,包括正在编辑的文件名、是否修改过、当前行号、文件的行数以及光标之前的行占整个文件的百分比。
   4. 屏幕调零命令
   Vi 提供了三个有关屏幕调零的命令。它们的格式分别为:
   · [行号] z [行数] < 回车 >
   · [行号] z [行数] .
   · [行号] z [行数] _
  若省略了行号和行数,这三个命令分别为将光标所在的当前行作为屏幕的首行、中间行和最末行重新显示;若给出行号,那么该行号所对应的行就作为当前行显示在屏幕的首行、中间行和最末行;若给出行数,则它规定了在屏幕上显示的行数。
  [例 13
   8z16< 回车 > :将文件中的第 8 行作为屏幕显示的首行,并一共显示 16 行。
   15z . :将文件中的第 15 行作为屏幕显示的中间行,显示行数为整屏。
   15z 5_ :将文件中的第 15 行作为屏幕显示的最末行,显示行数为 5 行。
  文本插入操作
  在命令模式下用户输入的任何字符都被 Vi 当作命令加以解释执行,如果用户要将输入的字符当作是文本内容时,则首先应将 Vi 工作 模式从命令模式切换到文本输入模式。切换的方式是使用下面的命令。
  插入( Insert )命令
   Vi 提供了两个插入命令: i I
   1. i 命令
  插入文本从光标所在位置前开始 , 并且插入过程中可以使用键删除错误的输入。此时 Vi 处于插入状态,屏幕最下行显示 “--INSERT--” (插入)字样。
  [例 14 有一正在编辑的文件,如下所示:
   Welcome to vi world!Come on!
   ~
   ~
  光标位于第一个 “!” 上,需在其前面插入:
   This is an example!
  使用 i 命令,并输入相应文本后,屏幕显示如下:
   Welcome to vi world This is an example!!Come on!
   ~
   ~
  由此例可以看到,光标本来是在第一个 “!” 处,但是由于是从光标所在位置前开始插入,所以这个 “!” 就被挤到了新插入的文本之后。
   2. I 命令
  该命令是将光标移到当前行的行首,然后在其前插入文本。
   vi 命令
  在屏幕上移动
   Vi 提供了三个关于光标在全屏幕上移动并且文件本身不发生滚动的命令。它们分别是 H M L 命令。
   1. H 命令
  该命令将光标移至屏幕首行的行首(即左上角),也就是当前屏幕的第一行,而不是整个文件的第一行。利用此命令可以 快速 将光标移至屏幕顶部。若在 H 命令之前加上数字 n ,则将光标移至第 n 行的行首。
  [例 9 屏幕显示如下内容:
   #include
   main
   { int k ;
   for k=0 ; k<3 ; k add ; }
   add
   { static int x=0;
   x ;
   printf “x=%d/n”, x ;
   }
   ~
   ~
   ~
   ~
   ~
   “example.c” New File
  在命令模式下输入 4H 命令后,光标移到以 for 开头的这一行的字母 f 上。
  值得一提的是,使用命令 dH 将会删除从光标当前所在行至所显示屏幕首行的全部内容。
   2. M 命令
  该命令将光标移至屏幕显示文件的中间行的行首。即如果当前屏幕已经充满 , 则移动到整个屏幕的中间行;如果并未充满,则移动到文本的那些行的中间行。利用此命令可以 快速 地将光标从屏幕的任意位置移至屏幕显示文件的中间行的行首。例如,在上面屏幕显示的情况下(不论光标在屏幕的何处),在命令模式下,输入命令 M 之后,光标都将移到 add 这一行的字母 a 上。
  同样值得一提的是,使用命令 dM 将会删除从光标当前所在行至屏幕显示文件的中间行的全部内容。
   3. L 命令
  当文件显示内容超过一屏时,该命令将光标移至屏幕上的最底行的行首;当文件显示内容不足一屏时,该命令将光标移至文件的最后一行的行首。可见,利用此命令可以快速准确地将光标移至屏幕底部或文件的最后一行。若在 L 命令之前加上数字 n ,则将光标移至从屏幕底部算起第 n 行的行首。例如,在上面屏幕显示的情况下(不论光标在屏幕的何处),在命令模式下,输入命令 3L 之后,光标都将移到 x 这一行的字母 x 上。
  同样值得一提的是,使用命令 dL 将会删除从光标当前行至屏幕底行的全部内容。
  按字移动光标
  首先介绍一下 Vi 的概念。在 Vi 有两种含义。一种是广义的字,它可以是两个空格之间的任何内容
  [例 10 在文件 example.c 中的第 4 行:
   {int k
  它只有 2 个字,一个是 {int ,另一个是 k;
   Vi 中另一种字是狭义上的字,在此种意义之下,英文单词、标点符号和非字母字符(如 ! @ # $ % ^ & * 、(、)、 - { } 、[、]、 ~ | / < > / 等)均被当成是一个字。因此,上面那一行中就包括 { int k 、;这 4 个字。
   Vi 中使用大写命令一般就是指将字作为广义来对待,使用小写命令就是作为狭义对待。
  搞清楚 Vi 中字的含义后,我们就可以介绍按字移动光标的命令了。
   Vi 一共提供了三组关于按字移动光标的命令,分别是:
   1. w W 命令
  将光标右移至下一个字的字首;
  [例 11 屏幕上显示如下:
   printf “Hello Mr.Huang!/n” ;
  现在使用 w 命令,把光标移到下一个字(狭义)的字首 上:
   printf “Hello Mr.Huang!/n” ;
  下面使用 W 命令,将把光标移到下一个字(广义)的字首 “M” 上:
   printf “Hello Mr.Huang!/n” ;
   2. e E 命令
  如果光标起始位置处于字内(即非字尾处),则该命令将把光标移到本字字尾;如果光标起始位置处于字尾,则该命令将把光标移动到下一个字的字尾。
   3. b B
  如果光标处于所在字内(即非字首),则该命令将把光标移至本字字首;如果光标处于所在字字首,则该命令将把光标移到上一个字的字首。
  [例 12 屏幕显示如下:
   printf “Hello Mr.Huang!/n” ;
  现在使用 b 命令,由于光标处于该字中间,所以光标移动到本字字首 “H” 处:
   printf “Hello Mr.Huang!/n” ;
  如果使用 B 命令,则如下所示:
   printf “Hello Mr.Huang!/n” ;
  按句移动光标
  在 Vi 中,一个句子被定义为是以逗号( , )、句号( . )、问号( ? )和感叹号( ! )结尾,且其后面跟着至少两个以上(含两个)空格或一个换行符的字符序列。
   Vi 提供了关于按句移动光标的两个命令,分别为:
   1. 命令
  将光标移 至上 一个句子的开头。
   2. 命令
  该命令将光标移至下一个句子的开头。
  按段移动光标
  在 Vi 中,一个段被定义为是以一个空白行开始和结束的片段。 Vi 提供了关于按段移动光标的两个命令,分别为:
   1. { 命令
  该命令将光标向前移至上一个段的开头;
   2. } 命令
  该命令将光标向后移至下一个段的开头。
  屏幕滚动
  屏幕命令是以屏幕为单位移动光标的,常用于文件的滚屏和分页。 需要 注意的是,屏幕命令不是光标移动命令,不能作为文本限定符用于删除命令中。
  在命令模式下和文本输入模式下均可以使用屏幕滚动命令。
   1. 滚屏命令
  关于滚屏命令有两个:
   · < Ctrl u > 将屏幕向前(文件头方向)翻滚半屏;
   · < Ctrl d > 将屏幕向后(文件尾方向)翻滚半屏。
  可以在这两个命令之前加上一个数字 n ,则屏幕向前或向后翻滚 n 行。并且这个值被系统记住,以后再用 < Ctrl u > < Ctrl d > 命令滚屏时,还滚相应的行数。
   2. 分页命令
  关于分页命令也有两个:
   · < Ctrl f > 将屏幕向文件尾方向翻滚一整屏(即一页);
   · < Ctrl b > 将屏幕向文件首方向翻滚一整屏(即一页)。 同样也可以在这两个命令之前加上一个数字 n ,则屏幕向前或向后移动 n 页。
   3. 状态命令 < Ctrl G >
  命令显示在 vi 状态行上的 vi 状态信息,包括正在编辑的文件名、是否修改过、当前行号、文件的行数以及光标之前的行占整个文件的百分比。
   4. 屏幕调零命令
   Vi 提供了三个有关屏幕调零的命令。它们的格式分别为:
   · [行号] z [行数] < 回车 >
   · [行号] z [行数] .
   · [行号] z [行数] _
  若省略了行号和行数,这三个命令分别为将光标所在的当前行作为屏幕的首行、中间行和最末行重新显示;若给出行号,那么该行号所对应的行就作为当前行显示在屏幕的首行、中间行和最末行;若给出行数,则它规定了在屏幕上显示的行数。
  [例 13
   8z16< 回车 > :将文件中的第 8 行作为屏幕显示的首行,并一共显示 16 行。
   15z . :将文件中的第 15 行作为屏幕显示的中间行,显示行数为整屏。
   15z 5_ :将文件中的第 15 行作为屏幕显示的最末行,显示行数为 5 行。
  文本插入操作
  在命令模式下用户输入的任何字符都被 Vi 当作命令加以解释执行,如果用户要将输入的字符当作是文本内容时,则首先应将 Vi 工作 模式从命令模式切换到文本输入模式。切换的方式是使用下面的命令。
  插入( Insert )命令
   Vi 提供了两个插入命令: i I
   1. i 命令
  插入文本从光标所在位置前开始 , 并且插入过程中可以使用键删除错误的输入。此时 Vi 处于插入状态,屏幕最下行显示 “--INSERT--” (插入)字样。
  [例 14 有一正在编辑的文件,如下所示:
   Welcome to vi world!Come on!
   ~
   ~
  光标位于第一个 “!” 上,需在其前面插入:
   This is an example!
  使用 i 命令,并输入相应文本后,屏幕显示如下:
   Welcome to vi world This is an example!!Come on!
   ~
   ~
  由此例可以看到,光标本来是在第一个 “!” 处,但是由于是从光标所在位置前开始插入,所以这个 “!” 就被挤到了新插入的文本之后。
   2. I 命令
  该命令是将光标移到当前行的行首,然后在其前插入文本。
   }
  第二十九课 vi 命令   
  附加( append )命令
   Vi 提供了两个附加插入命令: a A
   1. a 命令
  该命令用于在光标当前所在位置之后追加新文本。新输入的文本放在光标之后,在光标后的原文本将相应地向后移动。光标可在一行的任何位置。
  [例 15 以例 14 原始情况为例,使用 a 命令,并输入相应文本,屏幕显示如下:
   Welcome to vi world!This is an example!Come on!
   ~
   ~
  本例中光标后的文本 “Come on!” 被新输入的文本挤到了后面。
   2. A 命令
  该命令与 a 命令不同的是, A 命令将把光标挪到所在行的行尾,从那里开始插入新文本。当输入 A 命令后,光标自动移到该行的行尾。
   a A 命令是把文本插入到行尾的唯一方法。
  打开( open )命令
  不论是 Insert 命令也好,还是 append 命令也好,所插入的内容都是从当前行中的某个位置开始的。若我们希望在某行之前或某行之后插入一些新行,则应使用 open 命令。
   Vi 提供了两个打开命令: o O
   1. o 命令
  该命令将在光标所在行的下面新开一行,并将光标置于该行的行首,等待输入文本。要注意,当使用删除字符时只能删除从插入模式开始的位置以后的字符,对于以前的字符不起作用。而且还可以在文本输入方式下输入一些控制字符,例如, Ctrl l 即是插入分页符,显示为 ^L
  [例 16 以例 14 的原始情况为例,只是这次要在当前行下面一行输入文本。使用 o 命令,并输入相应文本,屏幕显示如下:
   Welcome to vi world!Come on!
   This is an example!
   ~
   ~
  新输入的文本出现在原来文本所在行的下一行。
   2. O 命令
  和 o 命令相反, O 命令是在光标所在行的上面插入一行,并将光标置于该行的行首,等待输入文本。
  [例 17 与例 14 的原始情况相同,要在当前行的上面一行输入文本。使用 O 命令并输入文本后,屏幕显示如下:
   This is an example!
   Welcome to vi world!Come on!
   ~
   ~
  文本插入到了当前行之上。
   11.3.4  文本修改
  在命令模式下可以使用 Vi 提供的各种有关命令对文本进行修改,包括对文本内容的删除、复制、取代和替换等。
  文本删除
  在编辑文本时,经常 需要 删除一些不需要的文本,我们可以用键将输错或不需要的文本删除,但此时有一个限制就是当删到行头之后,再想删上面那行的内容是不可能的。在命令模式下, Vi 提供了许多删除命令。这些命令大多是以 d 开头的。常用的有:
   1. 删除单个字符
   x 删除光标处的字符。若在 x 之前加上一个数字 n ,则删除从光标所在位置开始向右的 n 个字符。
   X :删除光标前面的那个字符。若在 X 之前加上一个数字 n ,则删除从光标前面那个字符开始向左的 n 个字符。
  显然这两个命令是删除少量字符的快捷方法。
   2. 删除多个字符
   dd :删除光标所在的整行。在 dd 前可加上一个数字 n ,表示删除当前行及其后 n-1 行的内容。
   D d$ :两命令 功能 一样,都是删除从光标所在处开始到行尾的内容。
   d0 :删除从光标前一个字符开始到行首的内容。
   dw :删除一个单词。若光标处在某个词的中间,则从光标所在位置开始删至词尾。同 dd 命令一样,可在 dw 之前加一个数字 n ,表示删除 n 个指定的单词。
  如果用户不小心进行了误删除操作,也不要紧, Vi 提供了恢复误操作的命令,并且可以将恢复的内容移动,放在文本的任何地方。恢复命令用 ² np ,其中 n 为寄存器号。这是因为 Vi 内部有 9 个用于维护删除操作的寄存器,分别用数字 1 2 ¼ 9 表示,它们分别保存以往用 dd 命令删除的内容。这些寄存器组成一个队列,例如最近一次使用 dd 命令删除的内容被放到寄存器 1 中;当下次再使用 dd 命令删除文本内容时, Vi 将把寄存器 1 的内容转存到寄存器 2 中,而寄存器 1 中又将是最近一次 dd 命令删除的内容。以此类推, Vi 可以保存有最近九次用 dd 命令删除的内容,而前面的用 dd 命令删除的内容则被抛弃。
  [例 18 假设当前编辑文件为 xu.c
   /* this is a example */
   #include
   void main
   {
   int i , j ;
   printf “ please input a number : / n ” ;
   scanf “ % d ” , &i ;
   j = i 100 ;
   printf “ /n j = % d /n ” , j ;
   return ;
   }
  我们对其进行如下操作:
   1. 将光标移至文件第一行,按 dd 命令,此时文件第一行的内容被删除,且被删除的内容保存在寄存器 1 中;
   2. 5j 使光标下移至第一个 printf 语句行;
   3. dd 命令将该行删除,此时寄存器 1 中将保存刚刚被删除的内容:
   printf “ please input a number :/ n ” ;
  而寄存器 1 原有的内容:
   /* this is a example */
  则被保存到寄存器 2 中;
  在最末行模式下,也可以对文件内容进行删除,但它只能删除整行,一次可将某个指定 范围 内(起始行号,终止行号)的所有行全部删除。 需要 注意的是,用此种方法进行删除时, Vi 并不把所删内容放入寄存器中,因而当发生误删除操作时,不能用 ² np 命令恢复,只能用 u 命令进行有限的恢复。
  最后提一下,如何在文本输入方式时将所输入文本删除。用户使用组合键 即可 ,此时光标将返回插入开始的位置,并且 Vi 仍处于文本输入方式。
  取消上一命令( Undo
  取消上一命令( Undo ),也称复原命令,是非常有用的命令,它可以取消前一次的误操作或不合适的操作对文件造成的影响,使之回复到这种误操作或不合适操作被执行之前的状态。
  取消上一命令有两种形式,在命令模式下键入字符 u U 。它们的功能都是取消刚才输入的命令,恢复到原来的情况。小写 u 和大写 U 在具体 细节 上有所不同,二者的区别在于,大写 U 命令的功能是恢复到误操作命令前的情况,即如果插入命令后使用 U 命令,就删除刚刚插入的内容;如果删除命令后使用 U 命令,就相当于在光标处又插入刚刚删除的内容。这里把所有修改文本的命令都视为插入命令。也就是说, U 命令只能取消前一步操作,如果用 U 命令撤消了前一步操作,当再按 U 键时,并不是撤消再前一步的操作,而是撤消了刚才 U 命令执行的操作,也就是又恢复到第一次使用 U 命令之前的状态,结果是什么都没做。而小写 u 命令的功能是把当前行恢复成被编辑前的状态,而不管此行被编辑了多少次。
  [例 19 原来屏幕显示内容为:
   #include
   main
   {
   }
  在命令模式下输入命令 o ,插入一新行,输入需要插入的内容后再按回到命令模式,屏幕显示内容为:
   #include
   main
   {
   printf “ How do you do ! ” ;
   }
  若想取消这一插入操作,请按命令 U 后,屏幕恢复到原来显示的情况。
  注意:对于取消命令仍可以再使用取消命令。这时会产生一种 负负得正 的效果,文件状态将恢复到第一次执行取消命令之前的状态,如同没做任何操作一般。例如在上例中,再使用一次命令 U ,屏幕将显示的内容仍为插入后的内容。
  重复命令( Redo
  重复命令也是一个非常常用的命令。在文本编辑中经常会碰到需要机械地重复一些操作,这时就需要用到重复命令。它可以让用户方便地再执行一次前面刚完成的某个复杂的命令。
  重复命令只能在命令模式下 工作 ,在该模式下按 “.” 键既可。执行一个重复命令时,其结果是依赖于光标当前位置的。
  [例 20 屏幕显示内容为:
   #include
   main
   {
   }
  输入命令 o ,并输入一行内容后,再 < Esc > 返回到命令模式下,屏幕显示内容为:
   #include
   main
   {
   printf “ How do you do ! ” ;
   }
  此时输入命令 “.” ,屏幕显示内容为:
   #include
   main
   {
   printf “ How do you do ! ” ;
   printf “ How do you do ! ” ;
  

你可能感兴趣的:(工作,linux,shell,File,insert,文本编辑)