在Vim搜索和替换中将变量与子匹配相结合

时间:2017-06-17 21:40:21

标签: vim replace

我有几行与此相似:

insert into team (lowernum, uppernum, position, color1, color2) values (15, 16, 32, "red", "green");

我想在vim中执行搜索并替换以更改每行上的第三个数字(在此示例中为108),使其增加15.因此,结果行将如下所示:

insert into team (lowernum, uppernum, position, color1, color2) values (15, 16, 47, "red", "green");

我已经尝试了几个搜索和替换选项,但还没有弄清楚如何将变量与子匹配组合以获得我想要的结果。我尝试过的一个例子是:

:%s/\((\d\d, \d\d, \)\(\d\d\)/\=\1 submatch(2) + 15/g

显然,这会产生错误,但我还没有找到实现替换子句的正确方法。这样做的正确方法是什么?

答案

根据romainl的回答,这是对我有用的解决方案:

:%s/\d\{1,}, \d\{1,}, \zs\(\d\{1,}\)/\=submatch(0) + 15/g

zs 表示将被替换的模式的开始。

2 个答案:

答案 0 :(得分:3)

这应该可以解决问题:

:s/\d\{2,}, \d\{2,}, \zs\(\d\{2,}\)/\=submatch(0) + 15

答案 1 :(得分:0)

经过一些研究,似乎不可能在vim或sed中的搜索/替换操作中实际进行算术。虽然如果它确实如此我也会非常感兴趣。我知道,我在评论中建议的UPDATE语句会影响整个表格,而不仅仅是该文件的插入值。

所以这是一个替代解决方案(假设您使用的是mysql):

用'tmp_team'替换该文件中每次出现的'team'。

然后添加到文件顶部:

CREATE TABLE tmp_team LIKE team;

开始编辑: 现在假设团队表在列id上有一个auto_increment主键,您必须将该键放在tmp表中并将其所有值设置为null:

-- getting rid of the auto_increment property:
ALTER TABLE tmp_team MODIFY id INT DEFAULT NULL;
-- dropping primary key:
ALTER TABLE tmp_team DROP PRIMARY KEY;
UPDATE tmp_team SET id = NULL;

结束编辑

在文件的底部:

UPDATE tmp_team SET position = position+15;
-- inserting NULL values into an auto_increment column, assigns
-- correct values to the new entries
INSERT INTO team SELECT * FROM tmp_team;
DROP TABLE tmp_team;

这样您只会影响该文件中团队的位置值。