在具有以特定图案开始的第二行的两条线之间插入线

时间:2013-09-22 20:17:23

标签: regex linux bash sed

我想在两条线之间插入一条线,只有当第二条线与某个图案相匹配时

例如输入文件如下:

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

我想在lineToInsertline 5之间以及patternline 10之间插入pattern

我试过这个命令:

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

我希望这可行,但只有匹配的模式仅存在于偶数行上才有效!!

那么,我怎样才能使用sed或任何其他工具/命令实现这一目标?以及为什么上一个命令不起作用?

4 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:3)

sedinsert command

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

答案 2 :(得分:2)

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

执行N命令后,您的缓冲区将为:

pattern\nline 2

随后:

line 3\nline 4

随后:

line 5 \npattern

等等。

在你的替换命令中,你在模式之前有一个换行符,所以它只会在pattern在第二行,或换句话说是偶数时才会成功。

使用,您可以避免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

答案 3 :(得分:2)

这可能适合你(GNU sed):

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

这将在模式空间中读取2行,然后在第二行的开头查找模式。如果找到模式,则将新行附加到第一行。它始终打印第一行,然后将其删除,从而调用$!N,而不像通常那样自动读取新行。当模式空间中已存在换行符(D)时,\n命令会覆盖新行的自动读取。

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

当然,使用以下方法可以更轻松地处理:

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