sed-根据模式删除前一行和当前行

时间:2019-04-23 04:05:23

标签: sed

我要根据下一行的模式匹配删除前一行和当前行

这是我的sample.txt

This is test line 11
This is test line 999
This is test line 12
This is test line 13
This is test line 16
This is test line 999
This is test line 17
This is test line 18

我要匹配模式999,并删除自身和上一行

我正在尝试此命令,但没有输出

sed -Ene ':a;N;/999/{d;}; ba; P' sample.txt

5 个答案:

答案 0 :(得分:3)

这可能对您有用(GNU sed):

sed 'N;/\n.*999/d;P;D' file

打开一个贯穿文件长度的两行运行窗口。

如果窗口的第二行包含999,请删除这两行。

否则,打印窗口的第一行,删除第一行并重复。

第1行或第2行或更多包含999的连续行的替代解决方案:

sed -n ':a;$!N;/\n.*999/{:b;n;/999/bb;ba};/999/!P;D' file

答案 1 :(得分:2)

在gnu sed上尝试

 sed -Ez 's/[^\n]*\n[^\n]*999\n//g' sample.txt

答案 2 :(得分:1)

请尝试以下操作(如果可以使用awk,则可以)。

awk 'prev && $NF!=999{print prev ORS FNR,$0;prev="";next} $NF==999{prev=""} $NF!=999{prev=FNR FS $0}'  Input_file

或者如果您的行数是偶数,并且希望打印最后一个奇数。

awk 'prev && $NF!=999{print prev ORS FNR,$0;prev="";next} $NF==999{prev=""} $NF!=999{prev=FNR FS $0} END{if(prev){print prev}}'  Input_file

答案 3 :(得分:1)

对于sed 1 解决方案,它可以处理所有边缘情况(前2行中为999或999的连续行):

  sed '
    1{
      /999/d  # Special case needed for line 1. Delete if it contains 999.
    }
    $!N     # Append next line. $!N stops exit w/o printing at EOF.
    /999/d  # If pattern space contains 999, d & begin next cycle.
    P       # If we get to here, there is no 999. Print to first newline.
    D       # Delete to first newline.                                   
  ' FILE

输出:

This is test line 12
This is test line 13
This is test line 17
This is test line 18

1 在BSD(Mac OS X)和GNU sed上都进行了测试。

答案 4 :(得分:1)

具有以下更全面的示例输入:

$ cat file
This is test line 999
This is test line 11
This is test line 999
This is test line 12
This is test line 13
This is test line 999
This is test line 999
This is test line 999
This is test line 14
This is test line 15
This is test line 16
This is test line 999
This is test line 17
This is test line 18

尝试一下:

$ cat tst.awk
$NF == 999 {
    prev = ""
    next
}
{
    printf "%s", prev
    prev = $0 ORS
}
END {
    printf "%s", prev
}

$ awk -f tst.awk file
This is test line 12
This is test line 14
This is test line 15
This is test line 17
This is test line 18

或者如果您想简洁而不是清晰度:

$ awk '$NF==999{p="";next} {printf "%s",p; p=$0 ORS} END{printf "%s",p}' file
This is test line 999
This is test line 11
This is test line 999
This is test line 12
This is test line 13
This is test line 999
This is test line 999
This is test line 999
This is test line 14
This is test line 15
This is test line 16
This is test line 999
This is test line 17
This is test line 18

请注意,即使行中除最后一个字段之外的其他部分包含999,或者如果最后一个字段为9999而不是目标999,以上内容仍然有效不需要在脚本中多次写入/测试999,例如,如果您要测试行中的第三个字段而不是最后一个字段,则可以将$NF更改为{{ 1}} =,如果您想测试整行的正则表达式,只需将$3更改为$NF==999,即使您的目标字符串包含regexp元字符,它也将起作用。在任何UNIX盒中的任何shell中的任何awk中。