如何删除与我给出的文本匹配的前2行(使用sed)?

时间:2016-04-23 15:48:16

标签: regex shell sed

如何删除与我给出的文本匹配的前2行(使用sed!)
例如:

#file.txt contains following lines :
abc
def
def
abc
abc
def

我想先删除2" abc"

2 个答案:

答案 0 :(得分:1)

使用“sed”

虽然@EdMorton指出sed不是这项工作的最佳工具(如果你想知道为什么,请参阅下面的答案,并将其与awk代码进行比较),我的研究表明解决广义问题

  

使用sed

删除与给定模式匹配的行的“N”到“M”
在我看来,确实是一个非常棘手的问题。关于如何替换sed匹配模式的“第N”次出现似乎有很多建议,但我发现删除特定匹配< strong> line (或一系列行)是一项复杂得多的事业。

虽然通过在有限状态机的基础上编写“sed脚本生成器”,可能最好地解决N,M和模式的任意值的广义问题,但OP要求的特殊情况的解决方案仍然很简单,可以手工编码。我必须承认我之前对sed命令语法的混淆错综复杂并不是很熟悉,但我发现这个挑战对于获得更多使用非平凡sed用法的经验非常有用。 / p>

无论如何,这是我的解决方案,用于删除文件中包含“abc”的行的前两个出现。如果有一个更简单的方法,我很想知道它,因为这花了我一些时间。

最后一点需要注意:这假定为GNU sed,因为我无法找到POSIX sed的解决方案:

sed -n ':1;/abc/{n;b2;};p;$b4;n;b1;:2;/abc/{n;b3;};p;$b4;n;b2;:3;p;$b4;n;b3;:4;q' file

或者,用更详细的语法:

sed -n '
    # BEGIN - look for first match
        :first;
        /abc/ {
            # First match found. Skip line and jump to second section
            n; bsecond;
        };
        # Line does not match. Print it and quit if end-of-file reached
        p; $bend;
        # Advance to next line and start over
        n; bfirst;
    # END - look for first match

    # BEGIN - look for second match
        :second;
        /abc/ {
            # Second match found. Skip line and jump to final section
            n; bfinal;
        }
        # Line does not match. Print it and quit if end-of-file reached
        p; $bend;
        # Advance to next line and start over
        n; bsecond;
    # END - look for second match

    # BEGIN - both matches found; print remaining lines
        :final;
        # Print line and quit if end-of-file reached
        p; $bend;
        # Advance to next line and start over
        n; bfinal;
    # END - print remaining lines

    # QUIT
    :end;
    q;
' file

答案 1 :(得分:0)

sed用于单个行上的简单替换,即全部。对于其他任何你应该使用awk:

$ awk '!(/abc/ && ++c<3)' file
def
def
abc
def