Vim搜索和替换,添加一个常量

时间:2021-06-17 16:49:39

I know this is a long shot, but I have a huge text file and I need to add a given number to other numbers matching some criteria.

我知道这是一个很长的尝试,但是我有一个很大的文本文件,我需要在其他符合某些条件的数字上添加一个给定的数字。

Eg.

如。

identifying text 1.1200
identifying text 1.1400

and I'd like to transform this (by adding say 1.15) to

我想对它进行变换(加入1。15

identifying text 2.2700
identifying text 2.2900

Normally I'd do this in Python, but it's on a Windows machine where I can't install too many things. I've got Vim though :)

通常我用Python做这个,但是在Windows机器上我不能安装太多东西。但我有勇气:

6 个解决方案

#1


17  

Here is a simplification and a fix on hobbs' solution:

下面是对霍布斯的解决方案的简化和修正:

:%s/identifying text \zs\d\+\(.\d\+\)\=/\=(1.15+str2float(submatch(0)))/

Thanks to \zs, there is no need to recall the leading text. Thanks to str2float() a single addition is done on the whole number (in other words, 1.15 + 2.87 will give the expected result, 4.02, and not 3.102).

多亏了\zs,没有必要再回忆起前言。多亏了str2float(),对整个数字做了一次加法(换句话说,1.15 + 2.87将给出预期的结果,4.02,而不是3.102)。

Of course this solution requires a recent version of Vim (7.3?)

当然,这个解决方案需要最近版本的Vim (7.3?)

#2


10  

You can do a capturing regex and then use a vimscript expression as a replacement, something like

您可以执行捕获regex,然后使用vimscript表达式作为替换,类似这样

:%s/\(identifying text \)\(\d\+\)\.\(\d\+\)/
  \=submatch(1) . (submatch(2) + 1) . "." . (submatch(3) + 1500)

(only without the linebreak).

(只是没有linebreak)。

#3


3  

Your number format seems to be a fixed one, so it's easy to convert to int and come back (remove the dot) add 11500 and put the dot back.

您的数字格式似乎是一个固定的格式,所以很容易转换为int,然后返回(删除点)添加11500,并将点放回。

:%s/\.//
:%normal11500^A " type C-V then C-a
:%s/....$/.&/

If you don't want to do that on all the lines but only the one which match 'identifying text' replace all the % by 'g/indentifying text/'

如果你不想对所有的行都这么做但只有匹配"识别文本"的行用" g/识别文本/ "替换所有的%

#4


1  

For integers you can just use n^A to add n to a number (and n^X to subtract it). I doubt whether that works for fractional numbers though.

整数可以使用n ^数量添加n(n ^ X减)。但我怀疑这是否适用于小数。

#5


1  

Well this might not be a solution for vim but I think awk can help:

这可能不是vim的解决方案,但我认为awk可以帮助:

cat testscript | LC_ALL=C awk '{printf "%s %s %s %s %.3f\n", $1,$2,$3,$4,$5+1.567   }'

and the test

和测试

this is a number 1.56
this is a number 2.56
this is a number 3.56

I needed the LC_ALL=C for the correct conversion of the floating point separator, and maybe there is a more elegant solution for printing the beginning/ rest of the string. And the result looks like:

我需要LC_ALL=C来正确转换浮点分隔符,也许还有一种更优雅的解决方案来打印字符串的开头/其余部分。结果是:

this is a number 3.127
this is a number 4.127
this is a number 5.127

#6


1  

Using macro

使用宏

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'

if you have 300 lines with this pattern just now making

如果你现在有300行这样的图案

300@a

#1


17  

Here is a simplification and a fix on hobbs' solution:

下面是对霍布斯的解决方案的简化和修正:

:%s/identifying text \zs\d\+\(.\d\+\)\=/\=(1.15+str2float(submatch(0)))/

Thanks to \zs, there is no need to recall the leading text. Thanks to str2float() a single addition is done on the whole number (in other words, 1.15 + 2.87 will give the expected result, 4.02, and not 3.102).

多亏了\zs,没有必要再回忆起前言。多亏了str2float(),对整个数字做了一次加法(换句话说,1.15 + 2.87将给出预期的结果,4.02,而不是3.102)。

Of course this solution requires a recent version of Vim (7.3?)

当然,这个解决方案需要最近版本的Vim (7.3?)

#2


10  

You can do a capturing regex and then use a vimscript expression as a replacement, something like

您可以执行捕获regex,然后使用vimscript表达式作为替换,类似这样

:%s/\(identifying text \)\(\d\+\)\.\(\d\+\)/
  \=submatch(1) . (submatch(2) + 1) . "." . (submatch(3) + 1500)

(only without the linebreak).

(只是没有linebreak)。

#3


3  

Your number format seems to be a fixed one, so it's easy to convert to int and come back (remove the dot) add 11500 and put the dot back.

您的数字格式似乎是一个固定的格式,所以很容易转换为int,然后返回(删除点)添加11500,并将点放回。

:%s/\.//
:%normal11500^A " type C-V then C-a
:%s/....$/.&/

If you don't want to do that on all the lines but only the one which match 'identifying text' replace all the % by 'g/indentifying text/'

如果你不想对所有的行都这么做但只有匹配"识别文本"的行用" g/识别文本/ "替换所有的%

#4


1  

For integers you can just use n^A to add n to a number (and n^X to subtract it). I doubt whether that works for fractional numbers though.

整数可以使用n ^数量添加n(n ^ X减)。但我怀疑这是否适用于小数。

#5


1  

Well this might not be a solution for vim but I think awk can help:

这可能不是vim的解决方案,但我认为awk可以帮助:

cat testscript | LC_ALL=C awk '{printf "%s %s %s %s %.3f\n", $1,$2,$3,$4,$5+1.567   }'

and the test

和测试

this is a number 1.56
this is a number 2.56
this is a number 3.56

I needed the LC_ALL=C for the correct conversion of the floating point separator, and maybe there is a more elegant solution for printing the beginning/ rest of the string. And the result looks like:

我需要LC_ALL=C来正确转换浮点分隔符,也许还有一种更优雅的解决方案来打印字符串的开头/其余部分。结果是:

this is a number 3.127
this is a number 4.127
this is a number 5.127

#6


1  

Using macro

使用宏

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'

if you have 300 lines with this pattern just now making

如果你现在有300行这样的图案

300@a