Henry Henry
  • JavaScript
  • TypeScript
  • Vue
  • ElementUI
  • React
  • HTML
  • CSS
  • 技术文档
  • GitHub 技巧
  • Nodejs
  • Chrome
  • VSCode
  • Other
  • Mac
  • Windows
  • Linux
  • Vim
  • VSCode
  • Chrome
  • iTerm
  • Mac
  • Obsidian
  • lazygit
  • Vim 技巧
  • 分类
  • 标签
  • 归档
  • 网站
  • 资源
  • Vue 资源
GitHub (opens new window)

Henry

小学生中的前端大佬
  • JavaScript
  • TypeScript
  • Vue
  • ElementUI
  • React
  • HTML
  • CSS
  • 技术文档
  • GitHub 技巧
  • Nodejs
  • Chrome
  • VSCode
  • Other
  • Mac
  • Windows
  • Linux
  • Vim
  • VSCode
  • Chrome
  • iTerm
  • Mac
  • Obsidian
  • lazygit
  • Vim 技巧
  • 分类
  • 标签
  • 归档
  • 网站
  • 资源
  • Vue 资源
GitHub (opens new window)
  • 说明
  • Vim

  • VSCode

  • Chrome

  • iTerm

  • mac

  • Obsidian

  • lazygit

  • 学习双拼
  • Vim 技巧

    • Vim 技巧 - 说明
    • Vim 技巧 - 以退为进
    • Vim 技巧 - 点范式
    • Vim 技巧 - 把撤销单元切成块
    • Vim 技巧 - 构造可重复的修改
    • Vim 技巧 - 用次数做简单的算术运算
    • Vim 技巧 - 能够重复,就别用次数
    • Vim 技巧 - 在插入模式中可即时更正错误
    • Vim 技巧 - 结识插入 - 普通模式
    • Vim 技巧 - 不离开插入模式,粘贴寄存器中的文本
    • Vim 技巧 - 重复执行面向行的可视命令
    • Vim 技巧 - 只要可能,最好用操作符命令,而不是可视命令
    • Vim 技巧 - 结识 Vim 的命令行模式
    • Vim 技巧 - 在一行或多个连续行上执行命令
      • 用行号作为地址
      • 用地址指定一个范围
      • 用高亮选区指定范围
      • 用正则指定范围
      • 用偏移对地址进行修正
      • 结论
    • Vim 技巧 - 使用‘:t’和‘:m’命令复制和移动行
    • Vim 技巧 - 在指定范围上执行普通模式命令
    • Vim 技巧 - 重复上次的 Ex 命令
    • Vim 技巧 - 把当前单词插入到命令行
    • Vim 技巧 - 回溯历史命令
    • Vim 技巧 - 运行 Shell 命令
    • Vim 技巧 - 将工作区切分成窗
    • Vim 技巧 - 区分实际行与屏幕行
    • Vim 技巧 - 通过查找进行移动
    • Vim 技巧 - 遍历改变列表
    • Vim 技巧 - 用无名寄存器实现删除、复制与粘贴操作
    • Vim 技巧 - 深入理解 Vim 寄存器
    • Vim 技巧 - 用寄存器中的内容替换高亮选区的文本
    • Vim 技巧 - 把寄存器的内容粘贴出来
    • Vim 技巧 - 宏的读取与执行
    • Vim 技巧 - 规范光标位置、直达目标以及中止宏
    • Vim 技巧 - 加次数回放宏
    • Vim 技巧 - 在连续的文本行上重复修改
    • Vim 技巧 - 给宏追加命令
    • Vim 技巧 - 编辑宏的内容
    • Vim 技巧 - 调整查找模式的大小写敏感性
    • Vim 技巧 - 查找使用 v 或 V 模式
    • Vim 技巧 - 界定单词的边界
    • Vim 技巧 - 转义问题字符
    • Vim 技巧 - 结识查找命令
    • Vim 技巧 - 在执行查找前预览第一处匹配
    • Vim 技巧 - 将光标偏移到查找匹配的结尾
    • Vim 技巧 - 利用查找历史,迭代完成复杂的模式
    • Vim 技巧 - 结识 substitute 命令
    • Vim 技巧 - 在文件范围内查找并替换每一处匹配
    • Vim 技巧 - 手动控制每一次替换操作
    • Vim 技巧 - 重用上次的查找模式
    • Vim 技巧 - 用寄存器的内容替换
    • Vim 技巧 - 重复上一次 substitute 命令
    • Vim 技巧 - 使用子匹配重排 CSV 文件的字段
    • Vim 技巧 - 自动补全整行文本
    • Vim 技巧 - 以 g 开头的命令
    • Vim 技巧 - 以 z 开头的命令
    • Vim 技巧-ctrl 命令
    • Vim 技巧
    • 每日一 Vim 笔记
  • 键盘侠
  • Vim 技巧
Henry
2022-09-06
目录

Vim 技巧 - 在一行或多个连续行上执行命令

很多 Ex 命令可以用 [range] 指定要操作的范围。我们可以用行号、位置标记或是查找模式来指定范围的开始位置及结束位置。

Ex 命令的优点之一是它们可以在某一范围内的所有行上执行。我们以下面这个简短的 HTML 文本作为示例:

我们将使用 :print 命令作为演示。这条命令只是简单地在 Vim 命令行下方回显指定行的内容,它不产生什么实际影响,不过可以用它来说明一个范围由哪些行构成。当然,你可以试着把以下示例中的 :print 换成诸如 :delete、:join、:substitute 或 :normal 这样的命令,这样就能真切地感受到 Ex 命令是多么有用。

# 用行号作为地址

如果输入一条只包含数字的 Ex 命令,那么 Vim 会把这个数字解析成一个地址,并把光标移动到该数字所指定的行上。例如,运行下面的命令将跳到文件的首行:

➾:1

再运行下面的命令将打印首行的字符

➾:print

《 <!DOCTYPE html>

此文件只包含 5 行内容,如果要跳到文件的末尾,既可以输入 :5,也可以用特殊符号 $:

➾:$

➾:p

《 </html>

我们在这里使用的是 :p,它是 :print 命令的简写。实际上,用不着分开执行这两条命令,可以像下面这样把这两条命令合成一条:

➾:3p

《 <head><title>Practical Vim</title></head>

此命令会把光标移到第 3 行,然后显示该行的内容。记住,这里用 :p 命令的目的只是为了进行讲解。如果你执行的是 :3d 命令,那么只需一条命令就可以跳到第 3 行并删除此行;而与之等效的普通模式命令,则要先执行 3G,再跟着执行 dd。因此,从这个例子就可以看出,Ex 命令执行得要比普通模式命令更快。

# 用地址指定一个范围

迄今为止,地址只是被当成一个单独的行号,不过我们也可以用它来指定一个范围,如下例所示:

➾:2,5p

《 <html>
  <head><title>Practical Vim</title></head>
  <body><h1>Practical Vim</h1></body>
</html>
1
2
3
4

此例会打印从第 2 行到第 5 行之间的每一行的内容(含第 2 行及第 5 行)。注意,运行完这条命令后,光标将停留在第 5 行。通常,一个范围具有如下的形式:

:{start},{end}

需注意的是 {start} 和 {end} 都是地址。到目前为止,我们已经看到过用行号作为地址,然而很快就会看到也能用查找模式或是位置标记作为地址。

符号 . 代表当前行的地址。因此,我们可以很容易地写出一个范围,用以代表从当前位置到文件末尾间的所有行:

➾:2

➾:.,$p

《 <html>
  <head><title>Practical Vim</title></head>
  <body><h1>Practical Vim</h1></body>
</html>
1
2
3
4

符号 % 也有特殊含义,它代表当前文件中的所有行:

➾:%p

《 <!DOCTYPE html>
<html>
  <head><title>Practical Vim</title></head>
  <body><h1>Practical Vim</h1></body>
</html>
1
2
3
4
5

这和运行 :1,$p是等效的。这种简写形式在和 :substitute 命令一起使用时非常普遍:

➾:%s/Practical/Pragmatic/

上述命令让 Vim 把每行内的第一个“Practical”替换为“Pragmatic”

# 用高亮选区指定范围

我们也可以用高亮选区选定一个范围,而不是用数字指定。如果我们先执行 2G,再跟着执行 VG,就会选中如下一个高亮选区:

如果现在按下 : 键,命令行上就会预先填充一个范围 :'<,'>。这个范围看起来有点晦涩难懂,不过你可以简单地把它理解为一个代表高亮选区的范围。接下来我们就可以输入一条 Ex 命令,使它在每个被选中的行上执行:

➾:'<,'>p

《 <html>
  <head><title>Practical Vim</title></head>
  <body><h1>Practical Vim</h1></body>
</html>
1
2
3
4

如果只是想对文件的部分内容执行 :substitute 命令,用这种方式定义范围会很方便。

符号 '< 是代表高亮选区首行的位置标记,而 '> 则代表高亮选区的最后一行,这些位置标记即使在退出可视模式后仍然存在。如果你尝试在普通模式下直接运行 :'<,'>p,它会始终回显上一次高亮选区所选中的内容。

# 用正则指定范围

Vim 也接受以正则作为一条 Ex 命令的地址,如下所示:

➾:/<html>/,/<\/html>/p

《 <html>
  <head><title>Practical Vim</title></head>
  <body><h1>Practical Vim</h1></body>
</html>
1
2
3
4

这个范围看起来比较复杂,但实际上它符合范围的一般形式:{start},{end}。在本例中,{start} 地址是 /<html>/,而 {end} 地址是 /<\/html>/。换句话说,这个范围由 <html> 开标签所在的行开始,到对应闭标签所在的行结束。

在此例中,用地址 :2,5 也可以获得同样的结果,并且这种表示方式更简洁,不过它也更不可靠。用正则指定范围的话,我们的命令总是对整个<html></html> 范围进行操作,无论这个范围包含多少行都没问题。

# 用偏移对地址进行修正

假设我们想对位于<html></html>之间的每一行都运行一条 Ex 命令,但是不想包括 <html> 及 </html> 标签所在的行,那么可以为之加上偏移:

➾:/<html>/+1,/<\/html>/-1p

《 <head><title>Practical Vim</title></head>
  <body><h1>Practical Vim</h1></body>
1
2

偏移的一般形式是这样的:

:{address}+n

如果 n 被省略,那么缺省偏移量为 1。{address} 可以是一个行号、一个位置标记,或是一个查找模式。

假设我们想对由当前行开始的特定几行执行一条命令,那么可以使用相对于当前行的偏移:

➾:2

➾:.,.+3p

符号 . 代表当前行,所以上例中的 :.,.+3 相当于 :2,5。

# 结论

定义范围的语法非常灵活,既可以混合搭配行号、位置标记以及查找模式,也可以对它们加以偏移。下表对用来构建 Ex 命令的地址及范围的符号进行了总结:

第 0 行在文件中并不真实存在,但它作为一个地址,在某些特定场景下会很有用处。特别是,在把指定范围内的行复制或移动到文件开头时,可以用它做 :copy{address} 及 :move{address} 命令的最后一个参数。

编辑 (opens new window)
#Vim
上次更新: 5/27/2023, 1:02:05 PM
Vim 技巧 - 结识 Vim 的命令行模式
Vim 技巧 - 使用‘:t’和‘:m’命令复制和移动行

← Vim 技巧 - 结识 Vim 的命令行模式 Vim 技巧 - 使用‘:t’和‘:m’命令复制和移动行→

最近更新
01
version 1.15
07-01
02
version 1.14
06-27
03
version 1.13
06-27
更多文章>
Theme by Vdoing | Copyright © 2017-2023 HenryTSZ | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式