代码之家  ›  专栏  ›  技术社区  ›  Mert Nuhoglu

在VIM中:g/^$/,/../-j(将多个空白行减少为一个空白行)是如何工作的?

  •  27
  • Mert Nuhoglu  · 技术社区  · 15 年前

    在文章中, Vim Regular Expressions ,oleg raisky发出以下命令,将多个空白行减少为一个空白行:

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

    有人能描述一下这是怎么工作的吗?

    我知道 :g 命令和正则表达式。但我不明白那部分是什么 /,/./-j 做。

    1 回复  |  直到 11 年前
        1
  •  49
  •   paxdiablo    11 年前

    它真的很有创意。让我们把它分解。这个 ex 命令

    g/^$/xyzzy
    

    将搜索所有空行并执行 xyzzy 命令(任意 前任 命令)。

    最棘手的是 木制的 你的命令是 另一种 替换命令:

    ,/./-j
    

    这个 ,/./- 指定范围。这是这样的 <start>,<end> 而且,因为逗号之前没有任何东西,所以它假定当前行(找到空白行的那一行)是开始。

    逗号后是 /./- 这意味着搜索下一个字符( . 表示任何字符),然后备份一行( / 是短的 /./-1 因为如果没有给出任何值,这个值就是隐含的)。你会找到那个图案的 . 在您操作的第一行之后的第一个非空白行上。

    换言之,范围的结尾是您当前正在操作的行之后或该行处的最后一个空行。

    然后在该范围内执行联接。

    如果范围的开始和结束是相等的(部分中只有一个空行),则join不做任何操作。如果它们不相等,join将把它们全部连接起来。

    这就是它将多个空行组合成一个空行的方式。

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

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

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

    对于第2行, ,/./-j 将设置从2到2的范围(下一个 . 在第3行找到,然后减去1)。范围2,2上的联接不起作用。

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

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

    换言之,由于删除了第6行到第8行(与第5行结合使用),因此之后全局命令不会对它们进行操作。我基于这样一个事实,即VIM文档声明了一个两通算法,一个用于标记行,一个用于执行操作。

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