4.3 vi 编辑模式实战
与 Emacs 编辑模式相比,vi 编辑模式为我们提供了更多的控制命令。相应地,在 vi 编辑模式下,我们能够操作的粒度也将更细。如果你以前从未使用过 vi 编辑模式的话,那么不妨在亲自体验一番之后再来作决定是否要继续用它。跟 vi 文本编辑器一样,Shell 的 vi 编辑模式也包含两种模式:插入模式和命令模式。在插入模式下,我们输入的字符为字符本身,并没有什么特殊含义,如:h 就是 h;而在命令模式中,我们所输入的字符则为用来执行编辑过程的命令,如:h 用来向左移动一个字符。默认情况下,我们进入的是插入模式。若是要进入命令模式,则需要我们按 Esc 键。在使用 vi 编辑模式时,我们有时候可能会感到迷糊,此刻到底处于哪种模式呢?遇到这种情况,不妨先按 Esc 键 回到命令模式再作进一步的操作。或许这算是选择 vi 编辑模式的小小代价吧。
4.3.1 移动命令
在 vi 编辑模式中,我们可以使用的光标移动命令参考表 4.4。
命令 | 作用 |
---|---|
h | 向左移动一个字符 |
l | 往右移动一个字符 |
b | 向左移动一个单词 |
w | 往右移动一个单词 |
e | 移到单词结尾 |
B、W、E | 与 b 、w 、e 类似,按不同的单词定义进行移动 |
0 | 移到行首 |
^ | 移到行首,但第一个字符为非空白字符 |
$ | 移到行尾 |
让我们输入一行命令来试试这些 vi 编辑模式中的移动命令:
首先,按 Esc 键进入命令模式,此时光标位于 command
结尾的 d
上。
其次,通过 h 和 l 按一个个字符左右移动很直白,无需我们多言。值得讨论的是 b、w、e 跟它们对应的大写形式的区别:简而言之,b、w、e 将停留在空白或标点符号处(如该命令行中的 ,
(逗号)),而 B、W、E 则仅仅停留在空白处。例如,我们按 b 会经过 ,
,而按 B 将跳过 ,
。假如你想要移动更快的话,那么可以用大写字母的命令。而小写字母命令则对于更细粒度的移动有用,比如路径名这种情形。
最后,0 和 ^ 都是移到命令行的开头,不过其差异是 0 的开头可以为空白,而 ^ 的开头则不允许。例如:
按 0 移到开头的空格,按 ^ 移到 cd
的 c
上,按 $ 移到行尾的 x
。
4.3.2 重复命令
在 vi 命令模式下,每个移动命令之前可以跟一个数字,用来将该命令重复执行多次。例如,3b 表示向左移动 3 个单词,5l 则表示往右移动 5 个字符。值得注意的是,因为 0 本身也是一个命令,所以将它放在命令前面是无效的重复计数。
4.3.3 添加文本
我们已经知道通过按 Esc 键可以进入 vi 命令模式,但是,在命令模式下又如何回到插入模式呢?你只需参考表 4.5 中的命令来执行即可。
命令 | 作用 |
---|---|
i | 在光标左边插入新的文本内容 |
a | 在光标右边追加新的文本内容 |
I | 在行开头插入新的文本内容 |
A | 在行结尾追加新的文本内容 |
请看例子:
假如我打算将该命令改为
那么可按以下方式执行编辑操作:
按 2h 将光标移到空格处,接着按 i 进入插入模式,然后输入新的 ,
。按 Esc 键回到命令模式后,继续按 I 以便在命令行开头插入 echo
。再次按 Esc 键进入命令模式,最后按 A 在命令行的尾部追加 editing mode
。
4.3.4 删除文本
利用 vi 模式提供的删除命令,我们不仅可以删除字符,而且也能删除单词,甚至整个命令行。这些删除命令参考表 4.6。
命令 | 作用 |
---|---|
x | 删除光标下的字符 |
X | 删除光标左边的字符 |
dm | m 为某个移动指令,如 db 删除光标左边的单词 |
D | 从光标处删除到行尾 |
dd | 删除整行内容 |
跟移动命令一样,在上述删除命令之前也可以带一个数字,以便多次执行该命令。例如,5x 将删除 5 个字符,而 3dw 将删除 3 个单词,这里 3 的顺序并不重要,d3w 仍然同样有效。
通过删除命令删除的内容,Shell 并没有丢弃,而是将其保留在了删除缓冲器中。稍后,我们可以执行 u 命令来恢复这些删除的内容。如果想要恢复更早时间删除的内容,则只需按 u 键多次即可。
另外一种更有用的方式是复制和粘贴。这样,我们能够在保留原有内容的同时,再储存一份拷贝,以便后续使用。vi 模式中复制及粘贴的命令参考表 4.7。
命令 | 作用 |
---|---|
ym | m 为某个移动命令,如yw 用来复制光标右边的单词 |
p | 在光标右边粘贴文本 |
P | p 的大写形式,在光标左边粘贴文本 |
在下面的例子中,我们将看到上述命令的用法:
先按 Esc 键进入命令模式,此时光标位于结尾的 e 上。按 x 将删除 e,按 X 将删除 a,按 db 将删除 interface 剩下的部分(只剩下字符 c),按 dd 则把整行内容都删掉。按 u 又还原刚删除的内容。
4.3.5 替换文本
当我们需要替换命令行中的内容时,除了在删除该内容后再进入插入模式重新输入外,也可以使用 vi 编辑模式所提供的文本替换命令。这些命令组合了删除与插入操作,用起来将更加直接。vi 编辑模式提供的文本替换命令参考表 4.8。
命令 | 作用 |
---|---|
cm | m 为某个移动命令,如 cw |
C | 从光标处删除到行尾,并进入插入模式 |
cc | 删除整行,并进入插入模式 |
r | 替换光标下的字符 |
R | 进入替换文本模式 |
s | 利用输入的字符来替换光标下的字符 |
要想搞明白这些替换命令如何工作,不妨来试试以下编辑练习:
同样的,我们按 Esc 键先进入命令模式,按 cb 将 kode 删除后进入了插入模式,我们输入新的内容 code。再次按 Esc,接着按 4b 左移到 show,按 r 将 s 替换成 S。
4.3.6 搜索字符
vi 编辑模式还提供了一组命令用于搜索命令行中的字符。利用这些命令,我们可以移动光标到特定的字符上。此外,将其跟 d 和 c 命令组合使用,还能够删除或更改从光标处到该字符的这一段文本。这些用于搜索字符的命令参考表 4.9。
命令 | 作用 |
---|---|
fc | 移动光标到 c 的下一处 |
Fc | 与 f 相反方向搜索,移动光标到 c 的上一处 |
tc | 移动光标到 c 左边的字符 |
Tc | 移动光标到 c 右边的字符 |
; | 重复上次的 f 或 F 命令 |
, | 以相反的方向重复上次的 f 或 F 命令 |
在下面的练习中,我们可以尝试上述字符搜索命令的用法:
在按 Esc 键进入命令模式后,按 fp 光标移到了 p 上,按 th 移到了 h 左边的 w。按 Fm 光标左移到 m 上。我们还可以试试其它的命令,以便熟悉这些命令的用途。
4.3.7 vi 编辑模式总结
从前面我们所讲的内容来看,vi 编辑模式比 Emacs 编辑模式提供了更多的编辑命令。乍一看,似乎很复杂。我们除了勤加练习以期熟悉这些编辑命令之外,还可以总结出以下规律,从而帮助我们更好的加深理解。如图 4.2 所示。
- 跟 Emacs 编辑模式一样,我们同样可以按照字、“词”、行这 3 个维度来梳理操作命令
- 删除命令 d 和更改命令 c 能够与移动命令组合使用
- 移动命令、删除命令、更改命令之前可以加数字用来多次执行