我正在处理固定宽度的文件格式,我需要增加某些列中的所有数字。我有一个简单的宏,它为一个数字添加一个值,移动到下一行并重复(如2aj)但是,这些数字从1开始,通常在10000以上结束,因此列宽度变得混乱,例如(下划线为空格,此示例仅涵盖从9到10的跳跃)
FOO_7_BAR
FOO_8_BAR
FOO_9_BAR
变为
FOO_9BAR
FOO_10_BAR
FOO_11_BAR
(注意会破坏我程序的新文本列)
当我需要时
FOO_9_BAR
FOO10_BAR
FOO11_BAR
我一直在手动浏览并删除前9列中的空格,然后是90,然后是900,但我正在寻找一种更强大的方法来处理这个,而不处理前10,100,1000等。使用不同的宏或任何手动输入。
感谢。
答案 0 :(得分:3)
我想出这种方式,我认为动画解释了自己:
最终结果是:
FOO 3 BAR
FOO 4 BAR
FOO 5 BAR
FOO 6 BAR
FOO 7 BAR
FOO 8 BAR
FOO 9 BAR
FOO10 BAR
FOO11 BAR
答案 1 :(得分:2)
这需要一些手动hackery,但它仍然比手动删除空格更好。
你也可以通过Vimscript编写一个自动执行此功能的函数!
首先,找到最短线的长度。你可以通过ex做到这一点。 :echo col("$")
在最短的一行。
然后,运行以下命令:
:g/.\{NUM\}/exec "norm! /[0-9]\<cr>X"
将上述命令中的NUM替换为您在上一步中获得的原始编号。
以下是对其工作原理的解释:
:g/.\{NUM\}/ Find lines that are too long
exec "norm! A common idiom: build a string to execute in normal mode
/[0-9]<cr> Find the first number on the line
X Delete the space before it (equivalent to "hx")
然后只需重复运行相同的命令(你可以通过按: Up 返回)直到所有行都是相同的长度在这种情况下会导致错误(因为它找不到任何匹配的行)。
以下是整个过程的简短动画:
答案 2 :(得分:1)
可以使用:s
和子替换表达式完成此操作。
:%s/\v([^0-9]*)(\d+)/\=strpart(submatch(1), 0, 5 - len(submatch(2))).submatch(2)
我们的想法是捕获数字前面的部分和数字本身。替换通过\=
执行vim表达式,将两个捕获组重新组合在一起。但是,通过strpart()
将第一个捕获组切割为固定宽度(本例中为5)减去第二个捕获组len(submatch(2))
的长度。
如需更多帮助,请参阅:
:h sub-replace-expression
:h strpart()
:h len()