如何在Vim中对一段代码添加行号?

77

如何在Vim中为打开文件的一系列行添加行号?不是使用:set nu这样只是显示行号,而是要将行号实际地作为前缀添加到每一行中?


这个问题适用于任何具有行尾标记的文件,而不仅仅是源代码文件。 - Ana Nimbus
8个回答

125

随着

:%s/^/\=line('.')/

编辑:总结评论。

这个命令可以根据需要进行调整。


假设你想要在可视选择的行前添加数字(V+移动),并且你希望编号从42开始。

:'<,'>s/^/\=(line('.')-line("'<")+42)/
如果你想在数字和旧文本之间添加一个字符串,只需将其连接到数字表达式中(在VimL中使用.)。
:'<,'>s/^/\=(line('.')-line("'<")+42).' --> '/
如果您需要将其作为文本进行排序,可能需要对结果进行零填充,可以使用printf0001、0002等进行填充,而不是使用1、2等。例如:
:%s/^/\=printf('%04d', line('.'))/

无论如何,如果您想要更多信息,请打开vim帮助::h :s,并遵循链接(|subreplace-special|,...,|submatch()|


2
@Jason offset可以是1-line("'<")。想知道为什么这样老的问题会出现在我的RSS中。 - ZyX
我猜这是由于这个新的响应引起的:https://dev59.com/tXVC5IYBdhLWcg3wjx_u#4674574 - Luc Hermitte
2
你可以尝试以下方法:阅读文档(在这里键入 :help :s),查看Vim技巧(http://vim.wikia.com)、他人编写的插件、官方邮件列表vim_use以及像这样的论坛。 - Luc Hermitte
我在帮助文档中找不到=line。我想知道在替换中可以用哪些其他命令来代替它。 - dsg
9
以防其他人需要知道,要在数字后面添加字符串,请执行以下操作::%s/^/\=line('.') . 'string'/。在我的情况下,我需要一个逗号,因为我正在给 CSV 文件中的行编号,所以我执行了 :%s/^/\=line('.') . ','/ - katy lavallee
显示剩余3条评论

39

cat -n 命令会在其输入中添加行号。你可以将当前文件通过管道传递给 cat -n 命令,并用它打印到标准输出的内容替换当前缓冲区。幸运的是,在 Vim 中,这种复杂的解决方案少于 10 个字符:

:%!cat -n

或者,如果您只想选择子集,请可视化选择该区域并键入以下内容:

:!cat -n

在你输入完成后,这将自动插入可视选择标记,效果如下:

:'<,'>!cat -n

为了删除行号,我建议使用Ctrl+v,这将允许您可视化选择一个矩形。然后您可以使用x删除该矩形。

如果您想让行号从0开始而不是1,该怎么办? - Nils
  1. 删除第一行,对剩下的内容进行编号。
- sjas
请注意,cat -n 在数字前面放置五个空格并在数字后面放置一个制表符。我的 cat 来自 GNU coreutils 9.1。 - Matthias Braun

26

在GNU系统上,使用外部的nl二进制文件:

:%!nl

2
cool nl -v 命令允许您指定编号应该从哪里开始,因此如果您想要第一行成为0行而不是1行,请使用 nl -v 0。 - Nils
2
使用 :'<,'>!nl -w1 -s'. ',在每个可视选择的行前加上“1.”、“2.”、“3.”等编号。 - Matthias Braun

7

在类Unix环境下,您可以使用cat或awk轻松生成行号,因为vim与shell具有友好的接口,所以vim中的所有内容都像在shell中一样有效。


来自Vim Tip28:
:%!cat -n

或者

:%!awk '{print NR,$0}'

如果您在MS-DOS、Win9x或Win2000中使用vim,您将失去这些工具包。以下是只使用vim实现此目的的非常简单的方法:

fu! LineIt()
  exe ":s/^/".line(".")."/"
endf

或者,由字母组成的序列与以上类似,同样简单易懂。
exe "s/^/".nr2char(line("."))."/" 

您还可以使用subst:

:g/^/exe ":s/^/".line(".")."^I/"

您也可以仅打印行而不将它们添加到文件中:

"有时候,特别是在编辑大型源文件时,将行号打印在纸上可能会很有用。
要做到这一点,您可以使用选项 :set printoptions=number:y 来激活此功能,并使用 :set printoptions=number:n 来禁用此功能。
如果始终应该打印行号,请将行 set printoptions=number:y 放置在 vimrc 中。"


在第一个例子中,您是不是想说的是“cat”而不是“call”? - Lance Roberts
以下的参考资料让它看起来应该是cat。我发现awk语句可以给我更多的数字::%!awk '{print 1000+NR*10,$0}'。现在唯一的问题(不算什么)是我的剥离语句::%s/^[0-9]*//在前面留下了额外的空格,引用\s似乎没有帮助。 - Lance Roberts
@Lance:好的,我已经相应地编辑了答案。你的具体问题可以作为本页面的一个答案;) - VonC
我已经使用 :%!cat -n 添加了行号,但是如何将它们删除? - Cristian
@VonC 感谢您的建议。我已在此处提出了一个新问题:http://stackoverflow.com/questions/36579720/how-to-remove-line-numbers-in-vim - Cristian
显示剩余3条评论

4

首先,如果需要,您可以删除现有的行号:

:%s/^[0-9]*//

接下来,您可以添加行号。 NR表示从1开始的当前行号,因此您可以对其进行一些数学运算以获得所需的编号。以下命令为您提供四位数的行号:

:%!awk '{print 1000+NR*10,$0}'

3

"VisIncr" 插件通常用于在文本中插入递增的数字、字母、日期或罗马数字等。您可以控制数字格式、填充等。因此,您可以通过 :s:g 命令或可视块插入的方式,在每行前面插入一个 "1",然后在可视块模式下突出显示该列,并运行插件中的命令。


2

1
如果有人想在使用这个优秀的答案插入行号后放置一个制表符(或一些空格),这里有一个方法。进入转义模式后,执行以下操作:
:%s/^/\=line('.').'    '/

^ 表示行的开头,%s 是替换指令。所以我们说在每行开头加上行号并添加4个空格,然后将替换前该行的内容放在这里,并对文件中的所有行执行此操作。

这将自动进行替换。或者,如果您希望命令要求您确认,请执行以下操作:

:%s/^/\=line('.').'    '/igc

附言:强大的vim :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接