使用 vi 编辑文件

概述

在本教程中,学习 vi 编辑器的基本用法,几乎所有 Linux 或 UNIX 系统上都提供了它。学习如何:

  • 使用 vi 导航文档
  • 使用基本的 vi 模式
  • 插入、编辑、删除、复制和查找文本

本教程将帮助您对 Linux Server Professional (LPIC-1) 考试 101 的主题 103 中的目标 103.8 进行应考准备。该目标的权重为 3。

前提条件

要从本系列教程中获得最大收获,您应该拥有 Linux 的基本知识和一个正常工作的 Linux 系统,您可以在这个系统上实践本教程中涵盖的命令。有时程序的不同版本会得到不同的输出格式,所以您的结果可能并不总是与这里给出的清单和图完全相同。

使用 vi 导航文本

vi 编辑器几乎肯定存在于每个 Linux 和 UNIX 系统上。事实上,如果系统只有一个编辑器,那么该编辑器很可能就是 vi,所以了解如何使用 vi 是值得的。本教程将介绍一些基本的 vi 编辑命令,但要获得完整的 vi 教程,请查阅手册页或其他优秀的图书。

启动和导航 vi

这些内容是提高技能的渐进知识路径的一部分。参见Linux系统管理基础:在控制台工作

大多数 Linux 发行版现在都附带了 vim(表示 V i IM proved,改进的 vi)编辑器,而不是经典的 vi。Vim 向后兼容 vi,拥有图形模式 (gvim) 以及标准的 vi 文本模式接口。 vi 命令通常是 vim 程序的别名或符号链接。vim 有多个版本:微型、小型、普通、大型和超大型。您可以使用以下命令确定您运行的 vim 版本和它包含哪些特性:

vi --version

您是否还记得前面的教程 “学习 Linux,101:进程执行优先级 ” 中介绍更改优先级的部分,我们希望更改运行的 count1.sh shell 脚本的优先级。或许您自己已经尝试过,就会发现该命令运行得太快了,以至于您没有足够的时间使用 renice 完成优先级更改。所以我们首先使用 vi 编辑器在文件的开头添加一行,让该命令休眠 20 分钟,以便我们有时间来更改优先级。

如果还没有编写 count1.sh 程序,可以在您的主目录中打开一个终端窗口并粘贴来自 CPU 密集型脚本 – count1.sh 的命令。这将在一个名为 lpi103-8 的目录中创建 count1.sh 并跳转到该目录。

CPU 密集型脚本 – count1.sh
ian@yoga-u15:~$ mkdir -p lpi103-8 && cd lpi103-8 && {
> echo 'x="$1"'>count1.sh
> echo 'echo "$2" $(date)'>>count1.sh
> echo 'while [ $x -gt 0 ]; do x=$(( x-1 ));done'>>count1.sh
> echo 'echo "$2" $(date)'>>count1.sh
> }
ian@yoga-u15:~/lpi103-8$ cat count1.sh
x="$1"
echo "$2" $(date)
while [ $x -gt 0 ]; do x=$(( x-1 ));done
echo "$2" $(date)

要编辑一个现有文件,可以使用 vi 命令并使用一个文件名作为参数。请参阅手册页或 参考资料 来获取许多可用选项的细节。现在只需要使用没有选项的命令:

vi count1.sh

这个命令应该会打开 count1.sh 文件。您会看到一个类似 使用 vi 编辑 count1.sh 的显示界面。如果使用 vim,一些单词或字符可能带有颜色。Vim 拥有一种语法突出显示模式(最初的 vi 编辑器中没有该模式),该模式默认情况下可能已在您系统上打开。

使用 vi 编辑 count1.sh
 x="$1"
 echo "$2" $(date)
 while [ $x -gt 0 ]; do x=$(( x-1 ));done
 echo "$2" $(date)
 ~
 ~
 ~
 ~
"count1.sh" 4 lines, 84 characters

vi 编辑器可追溯到还不是所有终端键盘都拥有光标移动键的时代,所以,在 vi 中可以完成的所有操作都可以使用标准打字机上通常可找到的键和另外两个键(比如 EscInsert )来完成。但是,如果有其他键可用,那么可以配置 vi 来使用这些键;您键盘上的大部分建都可以在 vi 中派上用场。由于此传承和早期终端连接的缓慢性质,vi 当之无愧地就获得了命令非常简单且神秘的评价。我们首先看看用于导航文件的键。

移动

这些命令帮助您在文件内移动:

  • h: 在当前行上左移一个字符。
  • j: 下移到下一行。
  • k: 上移到上一行。
  • l: 在当前行上右移一个字符。
  • w: 在当前行上移到下一个单词。
  • e: 在当前行上移动到下一个词尾。
  • b: 在当前行上移动到上一个词头。
  • Ctrl-f: 向前翻一页。
  • Ctrl-b: 向后翻一页。

如果您在任何这些命令前键入一个数字,该数字就是命令的执行次数。这个数字被称为 重复次数 或简单地称为 次数 。例如,5h 表示将会左移 5 个字符。您可以将重复次数与许多 vi 命令结合使用。

移动到行

以下命令可以帮助您移动到文件中的特定行:

  • G: 移动到文件中的某个特定行。例如,3G 移动到第 3 行。没有参数时,G 移动到文件的最后一行。
  • H: 相对移动到屏幕上的顶行。例如,3H 移动到从屏幕顶部往下第 3 行。
  • L: 与 H 类似,但移动与屏幕上的底行相对。因此,2L 移动到屏幕上倒数第二行。

练习这些命令,直到您熟悉文件中的移动。如果遇到麻烦和命令未按预期的运行,请继续阅读,学习如何退出文件。

退出 vi

对于一个新编辑器,需要知道的最有用的操作之一就是,如何在您执行任何不应执行的操作(比如销毁某个重要的配置文件)之前退出它。要退出 vi,可以保存或丢弃更改,或者从头重新启动。如果这些命令不起作用,那么您可能处于插入模式,稍后将会介绍该模式。如果存在怀疑,请按下 Esc 退出插入模式并返回到命令模式,这时这些命令应该会生效。

  • :q!: 退出文件的编辑并丢弃所有更改。这是消除麻烦的一个常见命令。
  • :w!: 写入文件(无论是否已修改)。尝试重写现有文件或只读取其他不可写的文件。您可以提供一个文件名作为参数,写入这个文件而不是您最初使用的文件。通常省略 ! 会更安全一些,除非您知道自己在做什么。
  • ZZ: 如果文件已修改,那么请写入它。然后退出。这是正常退出 vi 的常见命令。
  • :e!: 编辑文件的当前磁盘副本。这会重新加载文件,丢弃您执行的更改。如果磁盘副本出于其他原因已发生更改,而且您想要使用最新的版本,那么也可以使用此命令。
  • :!: 运行一个 shell 命令。键入该命令并按下 Enter 。在命令完成时,您会看到输出和一条返回到 vi 编辑状态的提示。

备注:

  1. 键入冒号 (:) 时,您的光标将移动到屏幕的底行,您可以在这里键入该命令和任何参数。
  2. 如果省略上述命令中的感叹号,您可能会收到一条错误消息,比如表明更改为保存或输出文件无法写入(例如您在编辑一个只读文件)的消息。
  3. : 命令具有更长的形式(:quit、:write、:edit),但这些更长的形式很少使用。

vi 模式

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

  • 命令模式: 在命令模式中,您在文件中移动并执行编辑操作,比如搜索文本,删除文本,更改文本等。通常,您一开始处于命令模式。
  • 插入模式: 在插入模式中,您将新文本键入到文件中的插入点处。要返回到命令模式,可以按下 Esc (Escape) 键。

这两种模式确定了编辑器的行为方式。您在插入模式下键入的任何内容都被视为要插入到文件中的文本。如果尝试键入一个命令但没有得到任何结果,或者字符出现在光标下,那么您可能忘记按下 Esc 来离开插入模式了。

编辑文本

学习在 vi 中打开一个文件,在其中移动并退出,学会这些之后,是时候学习如何编辑文件中的文本了。

修改文本

在需要插入、删除或修改文本时,使用以下命令。请注意,其中一些命令具有与小写形式类似的大写形式;请参阅下面的描述。

  • i: 在当前位置的字符的前面进入插入模式。键入您的文本并按下 Esc 返回到命令模式。使用 I 会在当前行的开头插入内容。
  • a: 在当前位置的字符的后面进入插入模式。键入您的文本并按下 Esc 来返回到命令模式。使用 A 会在当前行的末尾插入内容。
  • c: 使用 c 更改当前字符并进入插入模式来键入替换字符。
  • o: 在当前行下方打开一个新行来插入文本。使用 O 在当前行上方打开一行。
  • cw: 删除当前单词的剩余内容并进入插入模式来替换它。使用一个重复次数来替换多个单词。使用 c$ 来替换行尾。
  • dw: 与上面的 cw(和 c$)相同,但未进入插入模式。
  • dd: 删除当前行。使用一个重复次数来删除多行。
  • x: 删除光标位置的字符。使用一个重复次数来删除多个字符。
  • p: 将最后删除的文本放在当前字符之后。使用 P 可将它放在当前字符的前面。
  • xp: x 和 p 的这种组合是一种有用的命令。它将光标位置的字符与它右侧的字符交换。

搜索文本

您可以使用正则表达式在您文件中搜索文本:

  • /: 使用 / 后跟一个正则表达式在文件中向前搜索。
  • ?: 使用 ? 后跟一个正则表达式在文件中向后搜索。
  • n: 使用 n 在一个方向重复上次的搜索。

您可以在上述任何命令的前面添加一个表示重复次数的数字。所以 3/x 将从当前点开始查找第三次出现的 x,/x 后跟 2n 也是如此。类似地,2/^e 将从当前位置开始查找第二个以 e 开头的行。

请注意,该搜索在到达文件底部后将返回到顶部搜索。

获取帮助

vi 中另一个有用的命令是 help 命令,您可以键入 :help 来调用它。帮助信息将会在 vi 内打开,可以使用 :q 命令离开帮助并返回到工作中。如果您想要获得针对某个特定主题的帮助,比如换行,可以在 :help 命令后添加一个单词,例如: :help wrap

融会贯通

我们首先希望向 count1.sh 文件添加一行。为了保留原始版本并将修改后的版本保存为 count2.sh,我们可以在使用 vi 打开该文件后使用这些 vi 命令。请注意, 表示按下 Esc 键。

将一行添加到 count1.sh 中的编辑器命令
1GOsleep 20<Esc>:w! count2.sh:q

这些命令执行以下操作:

  • 1G: 移动到文件的第一行
  • O: 在它上方打开一个新行并进入插入模式
  • sleep 20: 您想要添加的新文本
  • : 按下 Esc 键返回到命令模式
  • :w! count2.sh: 将文件写入磁盘
  • :q: 关闭 vi

知道如何做之后就会很简单。

这是考试 101 – 主题 103:GNU 和 UNIX 命令的最新教程。请参阅我们的 系列路线图 ,了解本系列中其他教程的说明和链接。

本文翻译自:Learn Linux, 101: File editing with vi(2017-03-11)