在具有第二条线的两条线之间插入线条,以某种模式开始

我想要在两行之间插入一行,只要第二行匹配某个特定的模式

例如input文件如下:

pattern (match 1, line 1) line 2 line 3 line 4 line 5 (before pattern) pattern (match 2, line 5) line 7 line 8 line 9 line 10 (before pattern) pattern (match 3, line 11) line 12 

我想在line 5pattern之间以及line 10pattern之间插入lineToInsert

我试过这个命令:

 sed 'N;s/\n\(pattern\)/\n\ lineToInsert\n\1/' 

我期望这个工作,但它只适用于匹配的模式只存在于一个偶数行!

那么,我怎样才能达到这个使用sed或任何其他工具/命令? 以及为什么以前的命令不起作用?

用awk你可以做这样的事情:

 awk 'NR>1&&/pattern/{print "lineToInsert"}1' file 

sed有一个插入命令 :

 sed '1n; /^pattern/i line to insert' 

你已经有了一些解决方案,但是,为什么你不工作? 因为sed读取每一行, N读取下一行,并将其附加到当前行。 所以你把两行中的每一行保存到缓冲区中,并将替换命令应用到两个换行符中。

N命令执行后你的缓冲区将是:

 pattern\nline 2 

后来:

 line 3\nline 4 

后来:

 line 5 \npattern 

等等。

在你的替换命令中,你在模式之前有一个换行符,所以只有当pattern在第二行,或者换句话说,就是一个。

使用sed ,你可以避免N和逐行处理文件,不用担心换行符,如:

 sed '1! s/\(pattern\)/lineToInsert\n\1/' infile 

它产生:

 pattern line 2 line 3 line 4 line 5 lineToInsert pattern line 7 line 8 line 9 line 10 lineToInsert pattern line 12 

这可能适用于你(GNU sed):

 sed -e '$!N;/\npattern/a\insert line' -e 'P;D' file 

这将读取2行到模式空间,然后在第二行的开头寻找模式。 如果发现该模式,则将新行添加到第一行。 在任何时候,它都会打印第一行,然后删除它,从而调用$!N而不会像sed正常那样自动读取新行。 当换行符( \n )已经存在于模式空间中时, D命令覆盖了新行的自动读入。

因为你没有使用P;D组合,你总是一次读两行。

当然,这可以更容易地处理使用:

 sed '1n;/^pattern/i\insert new line' file # as in Glen Jackman's answer