【问题标题】:How do I insert line numbers in vim (or sed) if I want to skip some lines?如果我想跳过某些行,如何在 vim(或 sed)中插入行号?
【发布时间】:2021-02-22 19:30:37
【问题描述】:

我正在使用 vim 中的降价文件,我想给行编号。插入行号很简单:

:%s/^/\=printf('%-4d', line('.'))

但是有一个问题。我想忽略任何和所有标题行(##Header)并仍然保持数字顺序。这意味着我不能简单地插入实际的行号。忽略领先的主题标签没有问题,但我不知道如何保持准确的计数。

【问题讨论】:

  • 你说得对,我应该这样做。但下面的答案做得很好。

标签: vim sed


【解决方案1】:

使用vimsed 可能很难实现它,因为它们没有 有一个variable,可以根据情况进行修改。 如果awk 是您的选择,请尝试:

awk '!/^#/ {$0 = sprintf("%-4d", ++n) $0} 1' file.md > file_new.md

输入文件file.md 如下所示:

# Header 1
Lorem
ipsum
dolor
### Header 2
sit
amet

那么输出file_new.md将是:

# Header 1
1   Lorem
2   ipsum
3   dolor
### Header 2
4   sit
5   amet
  • 如果行以“#”开头,则满足条件!/^#/ 然后评估以下{...} 块。
  • 声明 $0 = sprintf("%-4d", ++n) $0 前置一个连续词 行号(仅在满足上述条件时)。
  • 最后的1 告诉awk 无论条件如何都打印当前行。

【讨论】:

    【解决方案2】:

    以下 Vim 命令适用于我的有限测试:

    :let i = 0 | v/^#/let i += 1 | s/^/\=i . ' '
    

    一般性:

    • | 标志着两个 Ex 命令之间的分隔。

    • g/<pattern>/<command> 在匹配<pattern> 的每一行上执行<command>

    • v/<pattern>/<command> 在与<pattern> 匹配的每一行 上执行相同操作。

    • 当使用:help :g:help :v 时,重要的是要知道第二个/ 之后的所有内容,包括|,都是<command> 的一部分,所以:

      :g/foo/cmd1 | cmd2
      

      不会做g/foo/cmd1 然后cmd2。相反,它将在每个匹配行上执行 cmd1cmd2

    具体说明:

    • :let i = 0 启动一个值为0 的迭代器,
    • v/^#/… 将在不以# 开头的每一行上执行命令的其余部分,
    • let i += 1 递增迭代器,
    • s/^/\=i . ' ' 在当前行前面加上迭代器的当前值,后跟一个空格。 :help \= 用于替换部分,因为它允许我们使用表达式,从而使用变量。

    【讨论】:

      【解决方案3】:

      这可能对你有用(GNU nl):

      nl -bp'^[^#]\|^$' file
      

      将对除以# 开头的非空行之外的所有行进行行号。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多