最实用的vim插入序列问题

Vim、Emacs配置和使用
回复
xwsnet
帖子: 23
注册时间: 2007-09-23 12:52

最实用的vim插入序列问题

#1

帖子 xwsnet » 2010-03-03 18:59

最实用的vim插入序列问题


由于工作需要,经常要编辑某些配置文件如:

代码: 全选

caclpenaltyindi         SRVGRP=GRP1 SRVID=100    MIN=2   MAX=30   RQADDR="queue12600"     REPLYQ=Y CLOPT="-A"
sys_msg                 SRVGRP=GRP1 SRVID=100    MIN=1   MAX=10   RQADDR="queue12700"     REPLYQ=Y CLOPT="-A"
settle_stat             SRVGRP=GRP1 SRVID=100    MIN=1   MAX=10   RQADDR="queue12800"     REPLYQ=Y CLOPT="-A"
bad_debt                SRVGRP=GRP1 SRVID=100    MIN=1   MAX=10   RQADDR="queue12900"     REPLYQ=Y CLOPT="-A"
site_verify             SRVGRP=GRP1 SRVID=100    MIN=1   MAX=10   RQADDR="queue13000"     REPLYQ=Y CLOPT="-A"
updating_sum_id         SRVGRP=GRP1 SRVID=100    MIN=1   MAX=10   RQADDR="queue13100"     REPLYQ=Y CLOPT="-A"
CreateAssociate         SRVGRP=GRP1 SRVID=100    MIN=1   MAX=10   RQADDR="queue13200"     REPLYQ=Y CLOPT="-A"
tux_tran_comm           SRVGRP=GRP1 SRVID=100    MIN=1   MAX=5    RQADDR="queue13300"     REPLYQ=Y CLOPT="-A"
return_systime          SRVGRP=GRP1 SRVID=100    MIN=1   MAX=10   RQADDR="queue13400"     REPLYQ=Y CLOPT="-A"
linetgstat              SRVGRP=GRP1 SRVID=100    MIN=1   MAX=10   RQADDR="queue13500"     REPLYQ=Y CLOPT="-A"
report_tg               SRVGRP=GRP1 SRVID=100    MIN=1   MAX=10   RQADDR="queue13600"     REPLYQ=Y CLOPT="-A"
DispelFund              SRVGRP=GRP1 SRVID=100    MIN=1   MAX=5    RQADDR="queue13700"     REPLYQ=Y CLOPT="-A"
由于SRVID的值不能相同,因此使用如下命令:

代码: 全选

:let i=100
:g/SRVID=[0-9]\{1,9\}/s//\=i/|let i=i+10
vim中执行上面两条命令后文本可变为:

代码: 全选

caclpenaltyindi         SRVGRP=GRP1 100    MIN=2   MAX=30   RQADDR="queue12600"     REPLYQ=Y CLOPT="-A"
sys_msg                 SRVGRP=GRP1 110    MIN=1   MAX=10   RQADDR="queue12700"     REPLYQ=Y CLOPT="-A"
settle_stat             SRVGRP=GRP1 120    MIN=1   MAX=10   RQADDR="queue12800"     REPLYQ=Y CLOPT="-A"
bad_debt                SRVGRP=GRP1 130    MIN=1   MAX=10   RQADDR="queue12900"     REPLYQ=Y CLOPT="-A"
site_verify             SRVGRP=GRP1 140    MIN=1   MAX=10   RQADDR="queue13000"     REPLYQ=Y CLOPT="-A"
updating_sum_id         SRVGRP=GRP1 150    MIN=1   MAX=10   RQADDR="queue13100"     REPLYQ=Y CLOPT="-A"
CreateAssociate         SRVGRP=GRP1 160    MIN=1   MAX=10   RQADDR="queue13200"     REPLYQ=Y CLOPT="-A"
tux_tran_comm           SRVGRP=GRP1 170    MIN=1   MAX=5    RQADDR="queue13300"     REPLYQ=Y CLOPT="-A"
return_systime          SRVGRP=GRP1 180    MIN=1   MAX=10   RQADDR="queue13400"     REPLYQ=Y CLOPT="-A"
linetgstat              SRVGRP=GRP1 190    MIN=1   MAX=10   RQADDR="queue13500"     REPLYQ=Y CLOPT="-A"
report_tg               SRVGRP=GRP1 200    MIN=1   MAX=10   RQADDR="queue13600"     REPLYQ=Y CLOPT="-A"
DispelFund              SRVGRP=GRP1 210    MIN=1   MAX=5    RQADDR="queue13700"     REPLYQ=Y CLOPT="-A"
其中

代码: 全选

SRVID=100
SRVID=100
SRVID=100
SRVID=100
SRVID=100
SRVID=100
SRVID=100
SRVID=100
SRVID=100
SRVID=100
SRVID=100
SRVID=100
变为了

代码: 全选

100
110
120
130
140
150
160
170
180
190
200
210
我想请问怎样才能把

代码: 全选

SRVID=100
SRVID=100
SRVID=100
……
替换为

代码: 全选

SRVID=100
SRVID=200
SRVID=300
……
最好能有一个比较通用的方法,而不是只针对本例子,如可能不会是

代码: 全选

SRVID=100
SRVID=100
SRVID=100
……
而是

代码: 全选

SRVID=8329
SRVID=921
SRVID=4222
……
这样的情况。


下面几条语句都无法完成:

代码: 全选

:g/SRVID=[0-9]\{1,9\}/s//SRVID=\=i/   |let i=i+10
:g/SRVID=[0-9]\{1,9\}/s//`SRVID=`\=i/ |let i=i+10
:g/SRVID=[0-9]\{1,9\}/s//"SRVID="\=i/ |let i=i+10
:g/SRVID=[0-9]\{1,9\}/s//'SRVID='\=i/ |let i=i+10
……
还有就是

代码: 全选

:let i=100
:g/SRVID=[0-9]\{1,9\}/s//\=i/|let i=i+10
中的管道符是起到什么作用?
怎样理解这里的管道符?


以上操作环境为:
RHEL 5.3
VIM - Vi IMproved 6.3 (2004 June 7, compiled Aug 10 2005 18:49:40)

谢谢各位大虾。
上次由 xwsnet 在 2010-03-22 20:59,总共编辑 3 次。
xwsnet
帖子: 23
注册时间: 2007-09-23 12:52

Re: 最实用的vim插入序列问题

#2

帖子 xwsnet » 2010-03-05 18:55

怎么没人理会呢啊,各位大大看看吧
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

Re: 最实用的vim插入序列问题

#3

帖子 eexpress » 2010-03-05 22:27

如果过于复杂,你应该在处理软件那边改改。处理这些数据,脚本是轻而易举的事情。根本不劳烦你手动的哦。
● 鸣学
头像
Strange
帖子: 1824
注册时间: 2006-05-19 9:54
来自: Shanghai

Re: 最实用的vim插入序列问题

#4

帖子 Strange » 2010-03-05 22:46

这几条不能用的原因是g命令的匹配错了

代码: 全选

:g/SRVID=[0-9]\{1,9\}/s//SRVID=\=i/ |let i=i+10
:g/SRVID=[0-9]\{1,9\}/s//`SRVID=`\=i/ |let i=i+10
:g/SRVID=[0-9]\{1,9\}/s//"SRVID="\=i/ |let i=i+10
:g/SRVID=[0-9]\{1,9\}/s//'SRVID='\=i/ |let i=i+10
这样就可以了。

代码: 全选

:g/SRVID=[0-9]\+/s/[0-9]\+/\=i/ | let i=i+100
| 的作用是分割两个命令,使得执行s命令之后,继续执行let命令让 i 自加100

顺便,常用这种序列操作的话,用插件可能比较方便,可以参考一下这个
http://www.vim.org/scripts/script.php?script_id=670
上次由 Strange 在 2010-03-05 22:49,总共编辑 1 次。
ニンニク入れますか?
x60 with gentoo
头像
lilydjwg
论坛版主
帖子: 4258
注册时间: 2009-04-11 23:46
系统: Arch Linux
联系:

Re: 最实用的vim插入序列问题

#5

帖子 lilydjwg » 2010-03-05 22:48

麻烦以后用下 code 标签。

g 命令中的那个管道是命令分隔符

代码: 全选

:h :bar
所以那个 g 命令在匹配行上执行了 s 和 let 这两条命令。

代码: 全选

:let i=100
:g/\(SRVID=\)\@<=\d\+/s//\=i/|let i=i+10
可以完成比较*不*通用的那个。\= 的用法见 :h sub-replace-\=

那个数字没有规律的那个,可以使用一个列表来保存数据,然后替换时再取出来。不过 Vim 真的不适合这样折腾,建议考虑 shell 脚本或者其它脚本语言。

另外,如果那些要修改的行对齐了的话,可以考虑 vis.vim 列块操作插件。递增操作可以考虑 increment.vim 插件。
xwsnet
帖子: 23
注册时间: 2007-09-23 12:52

Re: 最实用的vim插入序列问题

#6

帖子 xwsnet » 2010-03-22 20:37

谢谢Strange兄和lilydjwg兄的指点,现在我理解这些命令的用法了,也学到了怎么用vim解决序列的问题。

只是Strange兄得方法有一个缺点就是适用性不够强,只能解决每行第一次出现的数字,如果不是第一次就用不上了。

lilydjwg兄的方法很完美。
回复