Regex 将vim替换转换为sed、awk或类似unix命令的反向引用
嗨,我有一个命令,我一直在用它来处理vim中的文本文件;查找字符串R1,然后删除3行,其中2行位于带有该字符串的行下方。 这在vim中工作正常,但是对于大文件,速度非常慢:Regex 将vim替换转换为sed、awk或类似unix命令的反向引用,regex,unix,vim,awk,sed,Regex,Unix,Vim,Awk,Sed,嗨,我有一个命令,我一直在用它来处理vim中的文本文件;查找字符串R1,然后删除3行,其中2行位于带有该字符串的行下方。 这在vim中工作正常,但是对于大文件,速度非常慢: :1,$s/\(r1.*\n\)\(\(.*\n\){2}\)\(\(.*\n\)\{3}\)/\1\2/g 例如: R1 30049 109769 109769
:1,$s/\(r1.*\n\)\(\(.*\n\){2}\)\(\(.*\n\)\{3}\)/\1\2/g
例如:
R1 30049 109769 109769
101598 281921
6.56608e+006 2.82861e+006
1.19658e+006 1.19658e+006
-515145 -515145
-223257 627520
-101598 -281921
-6.56608e+006 -2.82861e+006
23.125 23.125
271.7 272.46
500 500
将成为:
R1 30049 109769 109769
101598 281921
6.56608e+006 2.82861e+006
-101598 -281921
-6.56608e+006 -2.82861e+006
23.125 23.125
271.7 272.46
500 500
这个命令(或类似命令)可以更快地在unix终端的sed或awk中运行吗
非常感谢sed:
sed -n '/^R1/{p;n;p;n;p;n;n;n;n};p;' file.txt
要使用备份就地编辑文件,请执行以下操作:
sed -n -i.bak '/^R1/{p;n;p;n;p;n;n;n;n};p;' file.txt
您可以使用Vim中的
:global
来解决这个问题,而不是使用多行正则表达式(这确实可能很慢):
:global/^R1/.+3,.+5delete _
这将搜索以
R1
开头的所有行,然后删除下面的三到五行(进入黑洞寄存器。您可以通过perl执行此操作
$ perl -00pe 's/(\bR1.*\n(?:.*\n){2})(.*\n){3}/\1/g' file
R1 30049 109769 109769
101598 281921
6.56608e+006 2.82861e+006
-101598 -281921
-6.56608e+006 -2.82861e+006
23.125 23.125
271.7 272.46
500 500
sed是一个很好的工具,用于在一行上进行简单的替换,但对于其他任何操作,只需使用awk即可:
$ awk '/R1/{start=NR+3;end=start+2} NR<start || NR>end' file
R1 30049 109769 109769
101598 281921
6.56608e+006 2.82861e+006
-101598 -281921
-6.56608e+006 -2.82861e+006
23.125 23.125
271.7 272.46
500 500
$awk'/R1/{start=NR+3;end=start+2}NRend'文件
R1 30049 109769 109769
101598 281921
6.56608e+006 2.82861e+006
-101598 -281921
-6.56608e+006-2.82861e+006
23.125 23.125
271.7 272.46
500 500
如上所述,在包含R1(NR+3)的行之后开始删除3行,并在该行之后停止2行(start+2)。如果您需要处理其他范围、其他模式或其他条件,那么使其工作的调整是清晰而简单的。尝试调整sed解决方案以删除20行而不是3行
如果出于某种原因,您更喜欢sed解决方案的简洁性,只需使用单字符变量名,并去掉空白:
awk '/R1/{s=NR+3;e=s+2}NR<s||NR>e' file
awk'/R1/{s=NR+3;e=s+2}NRe'文件
它比sed更简单,但仍然更易于维护和扩展,正如awk解决多行问题的方法一样。vim中的g/R1/+3、.+5d
(而不是恶魔regex)有什么问题?我相信这应该相当快。