【发布时间】:2021-02-22 19:30:37
【问题描述】:
我正在使用 vim 中的降价文件,我想给行编号。插入行号很简单:
:%s/^/\=printf('%-4d', line('.'))
但是有一个问题。我想忽略任何和所有标题行(##Header)并仍然保持数字顺序。这意味着我不能简单地插入实际的行号。忽略领先的主题标签没有问题,但我不知道如何保持准确的计数。
【问题讨论】:
-
你说得对,我应该这样做。但下面的答案做得很好。
我正在使用 vim 中的降价文件,我想给行编号。插入行号很简单:
:%s/^/\=printf('%-4d', line('.'))
但是有一个问题。我想忽略任何和所有标题行(##Header)并仍然保持数字顺序。这意味着我不能简单地插入实际的行号。忽略领先的主题标签没有问题,但我不知道如何保持准确的计数。
【问题讨论】:
使用vim 或sed 可能很难实现它,因为它们没有
有一个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 无论条件如何都打印当前行。【讨论】:
以下 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。相反,它将在每个匹配行上执行 cmd1 和 cmd2。
具体说明:
:let i = 0 启动一个值为0 的迭代器,v/^#/… 将在不以# 开头的每一行上执行命令的其余部分,let i += 1 递增迭代器,s/^/\=i . ' ' 在当前行前面加上迭代器的当前值,后跟一个空格。 :help \= 用于替换部分,因为它允许我们使用表达式,从而使用变量。【讨论】:
这可能对你有用(GNU nl):
nl -bp'^[^#]\|^$' file
将对除以# 开头的非空行之外的所有行进行行号。
【讨论】: