:g/^$/,/./-j (将多个空白行减少为一个空白) 在 vi​​m 中如何工作? [英] How does :g/^$/,/./-j (reduce multiple blank lines to a single blank) work in vim?

查看:28
本文介绍了:g/^$/,/./-j (将多个空白行减少为一个空白) 在 vi​​m 中如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在文章中,Vim 正则表达式,Oleg Raisky 给出以下命令将多个空行减少为单个空格:

In the article, Vim Regular Expressions, Oleg Raisky gives the following command to reduce multiple blank lines to a single blank:

:g/^$/,/./-j

有人可以描述一下这是如何工作的吗?

Can someone please describe how this works?

我知道 :g 命令和正则表达式.但我不明白 /,/./-j 部分的作用.

I know :g command and regular expressions. But I didn't understand what the part /,/./-j does.

推荐答案

这真的很巧妙.让我们分解一下.ex 命令

It really is quite ingenious. Let's break it down. The ex command

g/^$/xyzzy

将搜索所有空行并对每个空行执行 xyzzy 命令(任意 ex 命令).

will search for all empty lines and execute the xyzzy command (an arbitrary ex command) on each of them.

这里的棘手之处在于您的情况下的 xyzzy 命令是又一个替代命令:

The tricky bit here is that the xyzzy command in your case is yet another substitute command:

,/./-j

,/./- 指定一个范围.这是 <start>,<end> 的形式,并且由于逗号前没有任何内容,因此它假定当前行(您找到空行的那一行)是开头.

The ,/./- specifies a range. This is of the form <start>,<end> and, because there's nothing before the comma, it assumes the current line (the one where you found the blank line) is the start.

逗号后是 /./- 表示搜索下一个字符(. 表示任意字符)然后备份一行(/./-/./-1 的缩写,因为如果没有给出值,则隐含该值).您会在您正在操作的行之后的第一个非空行中找到该模式 ..

After the comma is /./- which means search for the next character (. means any character) then back up one line (/./- is short for /./-1 since the one is implied if no value is given). You'll find that pattern . on the first non-blank line following the one you're operating on.

换句话说,范围的结尾是您当前正在操作的行之后或所在行的最后一个空行.

In other words, the end of the range is the last blank line after or at the one you're currently operating on.

然后在该范围内执行连接.

Then you execute a join over that range.

如果范围的开始和结束相等(该部分中只有一个空行),则 join 什么都不做.如果它们不相等,则 join 会将它们全部加入.

If the start and the end of the range were equal (only one blank line was in the section), join does nothing. If they're not equal, join will join them all up.

这是将多个空行合并为一个的方式.

That's the way in which it combines multiple blank lines into one.

让我们看一个例子(行号不在文件中):

Lets look at an example (line numbers are not in the file):

1 Line 1
2
3 Line 3
4 Line 4
5
6
7
8
9 Line 9

:g 命令将查找所有空行并对其执行操作(第 2、5、6、7 和 8 行).

The :g command will find all blank lines and perform its operation on them (lines 2, 5, 6, 7 and 8).

对于第 2 行,,/./-j 将设置从 2 到 2 的范围(在第 3 行找到的下一个 . 然后减去 1).范围 2,2 上的连接什么也不做.

For line 2, ,/./-j will set up a range from 2 to 2 (next . found on line 3 then subtract 1). A join on the range 2,2 does nothing.

对于第 5 行,,/./-j 将设置从 5 到 8 的范围(在第 9 行找到的下一个 . 然后减去 1).范围 5,8 上的连接会将所有这些行连接在一起.

For line 5, ,/./-j will set up a range from 5 to 8 (next . found on line 9 then subtract 1). A join on the range 5,8 will join all those lines together.

我不完全确定这一点,但我认为该操作可能不会在作为早期操作的一部分消失的行上执行.这是因为处理循环中较早删除的行是没有意义的.

I'm not entirely certain about this but I think the operation may not be performed on lines that disappear as part of an earlier operation. That's because it would make no sense to process lines that have been deleted earlier in the cycle.

换句话说,因为第 6 行到第 8 行被删除(与第 5 行合并),因此之后全局命令不会对它们进行操作.我基于这样一个事实,即 vim 文档说明了一个两遍算法,一个标记行,一个执行操作.

In other words, because lines 6 through 8 are deleted (combined with line 5), the global command doesn't operate on them after that. I base that on nothing more than the fact that the vim documentation states a two-pass algorithm, one to mark the lines, one to perform the operation.

可能在这一点上是错误的(这不是第一次),但这是一个不影响功能的实现细节.

I may be wrong on that point (it wouldn't be the first time) but it's an implementation detail which doesn't affect the functionality.

这篇关于:g/^$/,/./-j (将多个空白行减少为一个空白) 在 vi​​m 中如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆