vi编辑器是Unix系统最初的编辑器。它使用控制台图形模式来模拟文本编辑窗口,允许查看
文件中的行、在文件中移动、插入、编辑和替换文本。

尽管它可能是世界上最复杂的编辑器(至少讨厌它的人是这么认为的),但其拥有的大量特
性使其成为Unix管理员多年来的支柱性工具。

在GNU项目将vi编辑器移植到开源世界时,他们决定对其作一些改进。由于它不再是以前
Unix中的那个原始的vi编辑器了,开发人员也就将它重命名为vi improved,或vim。

本节将会带你逐步了解使用vim编辑器编辑文本shell脚本文件的基础知识。

10.1.1 检查 vim 软件包

在开始研究vim编辑器之前,最好先搞明白你所用的Linux系统是哪种vim软件包。在有些发行
版中安装的是完整的vim,另外还有一个vi命令的别名,就像下面所显示的CentOS发行版中的那样。

$ alias vi
alias vi=’vim’
$
$ which vim
/usr/bin/vim
$
$ ls -l /usr/bin/vim
-rwxr-xr-x. 1 root root 1967072 Apr 5 2012 /usr/bin/vim
$

注意,上面的程序文件长列表中并没有显示出任何的链接文件(有关链接文件的详细内容请
参见第3章)。如果vim程序被设置了链接,它可能会被链接到一个功能较弱的编辑器。所以最好
还是检查一下链接文件。

在其他发行版中,你会发现各种各式各样的vim编辑器。要注意的是,在Ubuntu发行版中不
仅没有vi命令的别名,而且/usr/bin/vi程序属于一系列文件链接中的一环。

$ alias vi
-bash: alias: vi: not found
$
$ which vi
/usr/bin/vi
$
$ ls -l /usr/bin/vi
lrwxrwxrwx 1 root root 20 Apr 22 12:39
/usr/bin/vi -> /etc/alternatives/vi
$
$ ls -l /etc/alternatives/vi
lrwxrwxrwx 1 root root 17 Apr 22 12:33
/etc/alternatives/vi -> /usr/bin/vim.tiny
$
$ ls -l /usr/bin/vim.tiny
-rwxr-xr-x 1 root root 884360 Jan 2 14:40
/usr/bin/vim.tiny
$
$ readlink -f /usr/bin/vi
/usr/bin/vim.tiny

因此,当输入vi命令时,执行的是程序/usr/bin/vim.tiny。vim.tiny只提供少量的vim
编辑器功能。如果特别需要vim编辑器,而且使用的又是Ubuntu,那至少应该安装一个基础版本
的vim包。


说明 在上面的例子中,其实用不着非得连续使用ls –l命令来查找一系列链接文件的最终目
标,只需要使用readlink –f命令就可以了。它能够立刻找出链接文件的最后一环。


第9章已经详细讲解了软件安装。在Ubuntu发行版中安装基础版的vim包非常简单。

$ sudo apt-get install vim
[…]
The following extra packages will be installed: vim-runtime
Suggested packages:
ctags vim-doc vim-scripts
The following NEW packages will be installed:
vim vim-runtime
[…]
$
$ readlink -f /usr/bin/vi
/usr/bin/vim.basic
$

基础版的vim现在安装好了,/usr/bin/vi的文件链接会自动更改成指向/usr/bin/
vim.basic。以后再输入vi命令的时候,使用的就是基础版的vim编辑器了。

10.1.2 vim 基础

vim编辑器在内存缓冲区中处理数据。只要键入vim命令(或vi,如果这个别名或链接文件
存在的话)和要编辑的文件的名字就可以启动vim编辑器:
$ vim myprog.c

如在启动vim时未指定文件名,或者这个文件不存在,vim会开辟一段新的缓冲区域来编辑。
如果你在命令行下指定了一个已有文件的名字,vim会将文件的整个内容都读到一块缓冲区域来
准备编辑,如图10-1所示。
image.png
vim编辑器会检测会话终端的类型(参见第2章),并用全屏模式将整个控制台窗口作为编辑
器区域。

最初的vim编辑窗口显示了文件的内容(如果有内容的话),并在窗口的底部显示了一条消息
行。如果文件内容并未占据整个屏幕,vim会在非文件内容行放置一个波浪线(如图10-1所示)。

底部的消息行根据文件的状态以及vim安装时的默认设置显示了所编辑文件的信息。如果文
件是新建的,会出现消息[New File]。

vim编辑器有两种操作模式:

  •  普通模式
  •  插入模式

当你刚打开要编辑的文件时(或新建一个文件时),vim编辑器会进入普通模式。在普通模式
中,vim编辑器会将按键解释成命令(本章后面会讨论更多)。

在插入模式下,vim会将你在当前光标位置输入的每个键都插入到缓冲区。按下i键就可以进
入插入模式。要退出插入模式回到普通模式,按下键盘上的退出键(ESC键,也就是Escape键)
就可以了。

在普通模式中,可以用方向键在文本区域移动光标(只要vim能正确识别你的终端类型)。如
果你恰巧在一个古怪的没有定义方向键的终端连接上,也不是完全没有希望。vim中有用来移动
光标的命令。

  •  h:左移一个字符。
  •  j:下移一行(文本中的下一行)。
  •  k:上移一行(文本中的上一行)。
  •  l:右移一个字符。

在大的文本文件中一行一行地来回移动会特别麻烦,幸而vim提供了一些能够提高移动速度
的命令。

  •  PageDown(或Ctrl+F):下翻一屏。
  •  PageUp(或Ctrl+B):上翻一屏。
  •  G:移到缓冲区的最后一行。
  •  num G:移动到缓冲区中的第num行。
  •  gg:移到缓冲区的第一行。

vim编辑器在普通模式下有个特别的功能叫命令行模式。命令行模式提供了一个交互式命令
行,可以输入额外的命令来控制vim的行为。要进入命令行模式,在普通模式下按下冒号键。光
标会移动到消息行,然后出现冒号,等待输入命令。

在命令行模式下有几个命令可以将缓冲区的数据保存到文件中并退出vim。

  •  q:如果未修改缓冲区数据,退出。
  •  q!:取消所有对缓冲区数据的修改并退出。
  •  w filename:将文件保存到另一个文件中。
  •  wq:将缓冲区数据保存到文件中并退出。

了解了这些基本的vim命令后,你可能就理解为什么有人会痛恨vim编辑器了。要想发挥出vim
的全部威力,你必须知道大量晦涩的命令。不过只要了解了一些基本的vim命令,无论是什么环
境,你都能快速在命令行下直接修改文件。一旦适应了敲入命令,在命令行下将数据和编辑命令
一起输入就跟第二天性一样自然,再回过头使用鼠标反倒觉得奇怪了。

10.1.3 编辑数据

在插入模式下,你可以向缓冲区插入数据。然而有时将数据输入到缓冲区中后,你需要再对
其进行添加或删除。在普通模式下,vim编辑器提供了一些命令来编辑缓冲区中的数据。表10-1
列出了一些常用的vim编辑命令。
image.png
有些编辑命令允许使用数字修饰符来指定重复该命令多少次。比如,命令2x会删除从光标当
前位置开始的两个字符,命令5dd会删除从光标当前所在行开始的5行。


说明 在vim编辑器的普通模式下使用退格键(Backspace键)和删除键(Delete键)时要留心。
vim编辑器通常会将删除键识别成x命令的功能,删除当前光标所在位置的字符。vim编辑
器在普通模式下通常不识别退格键。


10.1.4 复制和粘贴

现代编辑器的标准功能之一是剪切或复制数据,然后粘贴在文本的其他地方。vim编辑器也
可以这么做。

剪切和粘贴相对容易一些。你已经看到表10-1中用来从缓冲区中删除数据的命令。但vim在
删除数据时,实际上会将数据保存在单独的一个寄存器中。可以用p命令取回数据。

举例来说,可以用dd命令删除一行文本,然后把光标移动到缓冲区的某个要放置该行文本的
位置,然后用p命令。该命令会将文本插入到当前光标所在行之后。可以将它和任何删除文本的
命令一起搭配使用。

复制文本则要稍微复杂点。vim中复制命令是y(代表yank)。可以在y后面使用和d命令相同
的第二字符(yw表示复制一个单词,y$表示复制到行尾)。在复制文本后,把光标移动到你想放
置文本的地方,输入p命令。复制的文本就会出现在该位置。

复制的复杂之处在于,由于不会影响到你复制的文本,你没法知道到底发生了什么。你无法
确定到底复制了什么东西,直到将它粘贴到其他地方才能明白。但vim还有另外一个功能来解决
这个问题。

可视模式会在你移动光标时高亮显示文本。可以用可视模式选取要复制的文本。要进入可视
模式,应移动光标到要开始复制的位置,并按下v键。你会注意到光标所在位置的文本已经被高
亮显示了。下一步,移动光标来覆盖你想要复制的文本(甚至可以向下移动几行来复制更多行的
文本)。在移动光标时,vim会高亮显示复制区域的文本。在覆盖了要复制的文本后,按y键来激
活复制命令。现在寄存器中已经有了要复制的文本,移动光标到你要放置的位置,使用p命令来
粘贴。

10.1.5 查找和替换

可以使用vim查找命令来轻松查找缓冲区中的数据。要输入一个查找字符串,就按下斜线(/)
键。光标会跑到消息行,然后vim会显示出斜线。在输入你要查找的文本后,按下回车键。vim
编辑器会采用以下三种回应中的一种。

  •  如果要查找的文本出现在光标当前位置之后,则光标会跳到该文本出现的第一个位置。
  •  如果要查找的文本未在光标当前位置之后出现,则光标会绕过文件末尾,出现在该文本所在的第一个位置(并用一条消息指明)。
  •  输出一条错误消息,说明在文件中没有找到要查找的文本。

要继续查找同一个单词,按下斜线键,然后按回车键。或者使用n键,表示下一个(next)。
替换命令允许你快速用另一个单词来替换文本中的某个单词。必须进入命令行模式才能使用替换命令。替换命令的格式是:

:s/old/new/

vim编辑器会跳到old第一次出现的地方,并用new来替换。可以对替换命令作一些修改来替换多处文本。

  •  :s/old/new/g:一行命令替换所有old。
  •  :n,ms/old/new/g:替换行号n和m之间所有old。
  •  :%s/old/new/g:替换整个文件中的所有old。
  •  :%s/old/new/gc:替换整个文件中的所有old,但在每次出现时提示。

如你所见,对一个命令行文本编辑器而言,vim包含了不少高级功能。由于每个Linux发行版
都会包含它,所以应该至少了解一下vim编辑器的一些基本用法。这样一来,不管所处的环境如
何,你总能编辑脚本。