删除模式匹配的行和下一行

删除模式匹配的行和下一行

我试图从文件中删除模式匹配的所有实例(如果它与模式匹配)。如果存在匹配,则具有匹配模式的(完整)行和下一行将被删除。

下一行始终出现在模式匹配的行之后,但除此之外它还出现在文件的其他区域中。

我正在使用 grep,它会按预期删除文件中下一行的所有出现位置。

有没有一种方法可以删除下一行当且仅当它位于模式匹配的行之后?

答案1

您可以sed使用Nd命令和一个{}堵塞:

sed -e '/pattern here/ { N; d; }'

对于匹配的每一行pattern here,都会执行 中的代码{}N也将下一行放入模式空间,然后d在继续下一行之前删除整个内容。这适用于任何 POSIX 兼容的sed.

答案2

如果您打开,大多数seds 不会打印最后一行。但 GNU会的。因此,如果您要删除的图案位于最后一行,它就会打印出来。有时最好保持缓冲区满 - 例如,始终保留 2 行N$sedN除了在您不想打印的行上。你可能会这样做:

seq 10 | sed -n 'x;/7/!g;//!p'

这是一个作为输入的示例seq。在每一行上,它都会交换保持空间和模式空间。如果最后保留的行与7 (在这种情况下)它将用当前行覆盖保留空间。然后它再次检查刚刚拉入的行(当前行)是否也与 不匹配7,否则它不会打印它。因此,它在每一行都会检查前一行和当前行。

1
2
3
4
5
6
9
10

如果你的模式确实落在最后一行:

seq 10 | sed -n 'x;/10/!g;//!p' 

1
2
3
4
5
6
7
8
9

另一个例子,希望更清楚地展示它将打印什么和不会打印什么:

sed -n 'x;/match/!g;//!p
' <<\DATA
    match 
    match 
    1not 
    2not 
    3not 
    4not 
    5not 
    match 
    6not 
    match                                                              
DATA

输出

2not
3not
4not
5not

答案3

awk 解决方案:

awk '/pattern/    { matched=1; next }
     1 == matched { matched = 0; next }
                  { print }' input-file

第 1 行查找与模式匹配的行,设置标志并跳过该行。第 2 行在设置标志时跳过一行,但重置标志。第 3 行打印未被其他两行之一跳过的行。

如果您愿意,可以在一行中输入:

awk '/pattern/{matched=1;next} 1==matched{matched=0;next} {print}' input-file

这是一个变体,可以让您控制要跳过的行数:

awk '/pattern/{skip=3;next} skip>0{--skip;next} {print}' input-file

设置skip为应跳过的行数(除了匹配的行之外)。

答案4

怎么样

sed '/pattern/ {$!N;d;}' file

相关内容