我知道这是一个长镜头,但我有一个巨大的文本文件,我需要将一个给定的数字添加到符合某些条件的其他数字。
例如。
identifying text 1.1200
identifying text 1.1400
我想将它(通过添加说 1.15)转换为
identifying text 2.2700
identifying text 2.2900
通常我会在 Python 中执行此操作,但它在我无法安装太多东西的 Windows 机器上。不过我有 Vim :)
我知道这是一个长镜头,但我有一个巨大的文本文件,我需要将一个给定的数字添加到符合某些条件的其他数字。
例如。
identifying text 1.1200
identifying text 1.1400
我想将它(通过添加说 1.15)转换为
identifying text 2.2700
identifying text 2.2900
通常我会在 Python 中执行此操作,但它在我无法安装太多东西的 Windows 机器上。不过我有 Vim :)
这是对霍布斯解决方案的简化和修复:
:%s/identifying text \zs\d\+\(.\d\+\)\=/\=(1.15+str2float(submatch(0)))/
多亏了\zs
,无需回忆开头的文字。由于对str2float()
整数进行了一次加法(换句话说,1.15 + 2.87 将给出预期的结果,即 4.02,而不是 3.102)。
当然,这个解决方案需要最新版本的 Vim(7.3?)
您可以执行捕获正则表达式,然后使用 vimscript 表达式作为替换,例如
:%s/\(identifying text \)\(\d\+\)\.\(\d\+\)/
\=submatch(1) . (submatch(2) + 1) . "." . (submatch(3) + 1500)
(只有没有换行符)。
您的数字格式似乎是固定的,因此很容易转换为 int 并返回(删除点)添加 11500 并将点放回。
:%s/\.//
:%normal11500^A " type C-V then C-a
:%s/....$/.&/
如果您不想在所有行上都这样做,但只有与“识别文本”匹配的行将所有 % 替换为“g/识别文本/”
对于整数,您只需使用n ^A 将n添加到数字(并使用n ^X 减去它)。我怀疑这是否适用于小数。
好吧,这可能不是 vim 的解决方案,但我认为 awk 可以提供帮助:
cat testscript | LC_ALL=C awk '{printf "%s %s %s %s %.3f\n", $1,$2,$3,$4,$5+1.567 }'
和测试
this is a number 1.56
this is a number 2.56
this is a number 3.56
我需要 LC_ALL=C 来正确转换浮点分隔符,也许有一个更优雅的解决方案来打印字符串的开头/其余部分。结果如下:
this is a number 3.127
this is a number 4.127
this is a number 5.127
使用宏
qa .......................... start record macro 'a'
/iden<Enter> ................ search 'ident*' press Enter
2w .......................... jump 2 words until number one (before dot)
Ctrl-a ...................... increases the number
2w .......................... jump to number after dot
1500 Ctrl-a ................. perform increases 1500 times
q ........................... stop record to macro 'a'
如果你现在有 300 行这种模式
300@a