我知道这很难实现,但我有一个巨大的文本文件,我需要将给定的数字添加到符合某些条件的其他数字。
例如:
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 :)
这里对hobbs'的解决方案进行了简化和修复:
:%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)
(仅排除换行符)。
您的数字格式似乎是固定的,因此很容易将其转换为整数并返回(去除小数点),然后加上11500再把小数点放回去。
:%s/\.//
:%normal11500^A " type C-V then C-a
:%s/....$/.&/
如果您不想在所有行上执行该操作,而只想在与“识别文本”匹配的行上执行该操作,请将所有%替换为“g / identifying text /”。
对于整数,您可以使用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
printf()
可以吗?(:h printf()) ->...\=printf('%.4f', 1.15+str2float(......))
- Luc Hermitte\=
允许替换字符串为一个表达式。(链接) - Bryce Guintastr2nr
。有关更多功能,请参见:h functions
。 - Bryce Guinta