【问题标题】:sed, awk or similar - delete whole line and 2 lines above if pattern matches followed by a blank linesed、awk 或类似的 - 如果模式匹配,则删除整行和上面的 2 行,后跟一个空行
【发布时间】:2017-02-10 16:52:31
【问题描述】:

示例文本:

heading1
heading2
data
data
data

heading1
heading2

heading1
heading2
data
data
data

我想删除中间没有任何数据的部分。那是;如果heading2后面有一个空行,删除heading2、heading1和上面的空行。

我发现了如何仅在后面跟着一个空行时删除行,以及如何删除模式上方/下方的 n 行,但不知道如何合并两者。

谢谢。

【问题讨论】:

    标签: linux bash awk sed


    【解决方案1】:

    你可以使用awk:

    awk 'BEGIN{RS=ORS="\n\n";FS="\n"} NF>2' input.file
    

    虽然awk 默认以每行为基础运行,但records 不一定需要是单行。使用RS输入记录分隔符)您可以定义如何分隔记录

    我将BEGIN 块中的RS 设置为空行以按段落分隔记录,并将FS 设置为换行符以通过换行符分隔字段。

    NFholds 是当前记录中的字段数。 NF>2 检查包含超过 2 行的任何记录 - 如果满足此条件,awk 将打印记录。

    ORS输出记录分隔符。我将其设置为空行,如FS,以便在输出中分隔各个记录。

    【讨论】:

    • 好的,这似乎可行。谢谢。我会在星期一更彻底地测试它(这是家庭时间,这与工作有关)。你能解释一下每个部分的作用吗?
    • @hek2mgl:现在正在尝试获得一个想法,++ 创新!
    • @mklement0 感谢您的编辑。虽然在这种情况下无关紧要,但我不知道默认 FS 在RS='' 时仍然有效除了换行符。 (即使手册明确指出!:))。我已经在想,使用 BEGIN{RS=ORS="\n\n";FS="\n"} 而不是一些需要解释的隐藏魔法可能会更好。
    • PS:只是意识到它实际上确实很重要,因为真实世界数据不太可能看起来像heading1。让我改变它
    【解决方案2】:

    这是一种类似的方法,可以消除打印最后一个空行:

    awk -v RS= 'NF>2{print sep $0; sep=ORS}' file
    

    【讨论】:

      【解决方案3】:

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

      sed ':a;N;/^$/M!ba;s/\n/&/3;t;d' file
      

      在模式空间中存储由空行分隔的记录。如果一条记录包含 3 个或更多换行符,则打印它,否则将其删除。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-13
        • 1970-01-01
        • 2021-01-30
        • 2012-08-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多