【问题标题】:Print lines between two patterns through sed/AWK when there is at least one line between them当两个图案之间至少有一条线时,通过 sed/AWK 打印它们之间的线
【发布时间】:2018-02-28 16:47:06
【问题描述】:

我正在尝试通过 sed 命令打印两个模式之间的线条。但是当它们之间有一些线时,我想在结果中包含包含 Pattern1 Pattern2 的线。如果 Pattern1 和 Pattern2 之间没有行,则也从文件中排除带有 Pattern1 和 Pattern2 的行。

PAT1
XXX
XXX
PAT2
PAT1
XX
PAT2
PAT1
PAT2
PAT1
XXX
PAT2

想要的输出是:

PAT1
XXX
XXX
PAT2
PAT1
XX
PAT2
PAT1
XXX
PAT2

【问题讨论】:

  • Stack Overflow 不是代码编写服务。请出示您的代码。由于 Stack Overflow 向您隐藏了关闭原因:寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定问题或错误以及在问题本身。没有明确问题陈述的问题对其他读者没有用处。请参阅:How to create a Minimal, Complete, and Verifiable example

标签: linux awk sed


【解决方案1】:
sed -n '/PAT1/{b A};b B; :A {N;/PAT2/b}; :B /PAT1/,/PAT2/p'

看到 PAT1 时,转到分支 A。在那里,读取下一行,如果它包含 PAT2,则重新开始。否则,打印 PAT1 和 PAT2 之间的行。

【讨论】:

    【解决方案2】:

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

    sed -n '/^PAT1/{:a;N;/^PAT2/M!ba;/\n.*\n/p}' file
    

    收集两个图案之间的线,并且仅在图案之间至少有一条线时打印。

    或者:

    sed '/^PAT1/h;//!H;/^PAT2/!d;x;/\n.*\n/!d' file
    

    如果一行以第一个模式开始,则替换保留空间中的任何内容。否则将该行附加到保留空间。如果该行不是以第二个模式开头,请将其删除。否则,如果没有至少三行,则交换到保留空间并将其删除。

    【讨论】:

      【解决方案3】:
      $ sed -n '/^PAT1/{N;/PAT2/d};/^PAT1/,/^PAT2/p' file
      

      首先,如果PAT1PAT2在连续的行中找到,则删除,然后使用range打印内容。

       n N    Read/append the next line of input into the pattern space.
      

      【讨论】:

        【解决方案4】:

        awk 来救援!

        $ awk '/PAT1/        {c=1; out=""} 
               /PAT2/ && c>2 {print out $0} 
               c&&c++        {out=out $0 ORS}' file
        
        PAT1
        XXX
        XXX
        PAT2
        PAT1
        XX
        PAT2
        PAT1
        XXX
        PAT2
        

        我认为它可以进一步简化,但现在读作要求。从 PAT1 开始,聚合行直到 PAT2,如果行数超过 2 则打印。

        【讨论】:

        • 这个问题很垃圾。回答它只会促进更多的垃圾。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-13
        • 1970-01-01
        • 1970-01-01
        • 2016-01-20
        • 1970-01-01
        相关资源
        最近更新 更多