Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 将vim替换转换为sed、awk或类似unix命令的反向引用_Regex_Unix_Vim_Awk_Sed - Fatal编程技术网

Regex 将vim替换转换为sed、awk或类似unix命令的反向引用

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

嗨,我有一个命令,我一直在用它来处理vim中的文本文件;查找字符串R1,然后删除3行,其中2行位于带有该字符串的行下方。 这在vim中工作正常,但是对于大文件,速度非常慢:

: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)有什么问题?我相信这应该相当快。