我想在匹配的模式之前和之后注释(#)6行。我提出了这个问题。
How do I delete a matching line, the line above and the one below it, using sed?
我试着对这个解决方案使用hold buffer,但不起作用。
我在一个文件中多次出现以下序列:
aaaa
bbbb
cccc
dddd
eeee
ffff
gggg
hhhh
iiii
jjjj
kkkk
llll
mmmm
nnnn
oooo 如果我搜索hhhh,那么输出文件应该如下所示:
aaaa
#bbbb
#cccc
#dddd
#eeee
#ffff
#gggg
#hhhh
#iiii
#jjjj
#kkkk
#llll
#mmmm
#nnnn
oooo 请帮助我使用sed或任何其他脚本执行此操作!
发布于 2013-06-25 23:31:17
这可能适用于您(GNU sed):
sed -r ':a;s/\n/&/6;tb;$!{N;ba};:b;/SEARCH_STRING/!{P;D};s/\n/&/12;tc;$!{N;bb};:c;s/^/#/gm' file发布于 2013-06-25 20:32:54
这个问题被标记为Vim,所以…我心爱的:help :global和:help :normal来拯救我!
:g/hhhh/-6,+6norm I#:substitute变体:
:g/hhhh/-6,+6s/^/#细目:
:global命令用于为匹配给定模式的每一行执行Ex命令。:g/hhhh/d会删除包含hhhh.
5,15和/或相对行号-3,+41。命令会删除上面6行和下面6行之间的所有内容。每行包含hhhh.
:normal命令都允许我们从命令行执行普通命令,并且它接受一个范围,就像其他Ex命令一样。I#是在行首插入#的最简单方法,因此我们可以从命令行执行:normal I#,这将我们带到第一个解决方案::g/hhhh/-6,+6norm I#
:substitute还接受一个范围,因此我们也可以使用它在范围中的每一行的开头插入一个#,这将我们带到第二个解决方案::g/hhhh/-6,+6s/^/#
发布于 2013-06-25 20:37:40
要在Perl中做到这一点,您需要将整个文件读入一个数组,然后找到匹配行的索引并编辑周围的行,这可以通过一个范围来完成。
您必须从数组切片中删除未定义的值,否则,如果匹配项接近文件的开头或结尾(即少于6行),则将创建新条目。
perl -we '@a = <>; # read whole file
for (0 .. $#a) { # loop over indexes
if ($a[$_] =~ /hhhh/) { # find match
s/^/#/ for grep defined, @a[$_-6 .. $_+6] # edit
}
}; print @a" hhh.txt在for循环中,$_是元素的别名,这就是为什么我们可以直接对它应用替换s///的原因。
这也可以通过使用Tie::File来简化。
输出:
aaaa
#bbbb
#cccc
#dddd
#eeee
#ffff
#gggg
#hhhh
#iiii
#jjjj
#kkkk
#llll
#mmmm
#nnnn
oooohttps://stackoverflow.com/questions/17297046
复制相似问题