简体   繁体   English

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

[英]How do i delete first 2 lines which match with a text given by me ( using sed )?

How do i delete first 2 lines which match with a text given by me ( using sed ! )我如何删除与我提供的文本匹配的前 2 行(使用 sed !)
Eg :例如:

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

And i want to delete first 2 "abc"我想删除前 2 个“abc”

Using "sed"使用“sed”

While @EdMorton has pointed out that sed is not the best tool for this job (if you wonder why exactly, see my answer below and compare it to the awk code), my research showed that the solution to the generalized problem虽然@EdMorton 指出sed不是这项工作的最佳工具(如果您想知道为什么,请参阅下面我的答案并将其与awk代码进行比较),但我的研究表明,通用问题的解决方案

Delete occurences "N" through "M" of a line matching a given pattern using sed使用sed删除匹配给定模式的行中出现的“N”到“M”

indeed is a very tricky one in my opinion.在我看来确实是一个非常棘手的问题。 There seem to be many suggestions for how to replace the "N"th occurence of a matching pattern with sed , but I found that deleting a specific matching line (or a range of lines) is a much more complex undertaking.关于如何用sed替换匹配模式的“第 N”次出现,似乎有很多建议,但我发现删除特定匹配(或一系列行)是一项复杂得多的工作。

While the generalized problem with arbitrary values for N, M, and the pattern would probably be solved best by writing a "sed script generator" on the basis of a Finite State Machine, the solution to the special case asked by the OP is still simple enough to be coded by hand.虽然通过在有限状态机的基础上编写“sed 脚本生成器”可以最好地解决 N、M 和模式的任意值的广义问题,但 OP 提出的特殊情况的解决方案仍然很简单手动编码就够了。 I must admit that I wasn't very familiar with the obfuscated intricacies of the sed command syntax before, but I found this challenge to be quite useful for gaining more experience with non-trivial sed usage.我必须承认,我之前不太熟悉sed命令语法的复杂性,但我发现这个挑战对于获得更多非平凡sed用法的经验非常有用。

Anyway, here's my solution for deleting the first two occurences of a line containing "abc" in a file.无论如何,这是我删除文件中包含“abc”的行的前两次出现的解决方案。 If there's a simpler approach, I'm eager to learn about it, as this has taken me some time now.如果有更简单的方法,我很想了解它,因为这花了我一些时间。

A final caveat: this assumes GNU sed , as I was unable to find a solution with POSIX sed :最后一个警告:这假设 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

or, in more verbose syntax:或者,在更详细的语法中:

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

sed is for simple substitutions on individual lines, that is all. sed 用于单个行上的简单替换,仅此而已。 For anything else you should be using awk:对于其他任何事情,您都应该使用 awk:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM