【问题标题】:How to delete 2 consecutive lines only when both patterns are matched仅当两个模式都匹配时,如何删除连续的 2 行
【发布时间】:2023-03-10 06:25:02
【问题描述】:

让我们考虑这个简单的文件:

{
bla bla
bla bla bla
}
{
bla bla
bla bla bla
}
bla bla
bla bla bla

我只需要删除那些连续的行:

}
{

结果应该是:

{
bla bla
bla bla bla
bla bla
bla bla bla
}
bla bla
bla bla bla

我尝试了以下方法:

sed -e '/^}$/,/^{$/d' file

很遗憾,最后一个右大括号和剩余的行已被删除:

{
bla bla
bla bla bla
bla bla
bla bla bla

有什么建议吗?

如有必要,我愿意接受任何涉及其他工具(例如 awk/perl/...)的简单解决方案。

【问题讨论】:

    标签: perl awk sed


    【解决方案1】:

    你也可以使用这个awk:

    awk 'BEGIN{RS="";FS=OFS="\n"}{print $1,$2,$3,$6,$7,$8,$9,$10}' file
    {
    bla bla
    bla bla bla
    bla bla
    bla bla bla
    }
    bla bla
    bla bla bla
    

    或者使用for循环:

    
    awk 'BEGIN{RS="";FS=OFS="\n"}{
            for(i=1;i<=NF;i++) {
                    if(i == 4 || i == 5) continue; print $i}
    }' file
    {
    bla bla
    bla bla bla
    bla bla
    bla bla bla
    }
    bla bla
    bla bla bla
    

    【讨论】:

      【解决方案2】:

      使用 GNU sed for -z:

      $ sed -z 's/}\n{\n//' file
      {
      bla bla
      bla bla bla
      bla bla
      bla bla bla
      }
      bla bla
      bla bla bla
      

      使用 GNU awk 进行多字符 RS:

      $ awk -v RS='}\n{\n' -v ORS= '1' file
      {
      bla bla
      bla bla bla
      bla bla
      bla bla bla
      }
      bla bla
      bla bla bla
      

      【讨论】:

        【解决方案3】:
        $ sed '$!N;/^}\n{$/d;P;D' file
        {
        bla bla
        bla bla bla
        bla bla
        bla bla bla
        }
        bla bla
        bla bla bla
        

        这两个行缓冲区也适用于其他输入,如以下测试:

        $ cat test
        }
        }
        {
        foo
        }
        $ sed '$!N;/^}\n{$/d;P;D' test
        }
        foo
        }
        

        【讨论】:

          【解决方案4】:

          你可以使用这个sed:

          sed '/^}$/ { N; /\n{$/ d; }' file
          
          {
          bla bla
          bla bla bla
          bla bla
          bla bla bla
          }
          bla bla
          bla bla bla
          

          内联保存更改:

          sed -i.bak '/^}$/ { N; /\n{$/ d; }' file
          

          或者这个awk 也可以工作:

          awk '/^}$/ {p = $0; next} p != "" {if (/^{$/) {p=""; next} $0 = p ORS $0; p = ""} 1' file
          
          {
          bla bla
          bla bla bla
          bla bla
          bla bla bla
          }
          bla bla
          bla bla bla
          

          【讨论】:

            【解决方案5】:

            Perl 解决方案:

            perl -lne 'undef $prev, next if $prev eq "}" && $_ eq "{";
                       print $prev if defined $prev;
                       $prev = $_;
                       END { print $prev if defined $prev}' -- file
            
            • -n 逐行读取输入并运行每一行的代码。
            • -l 从输入中删除换行符并将它们添加到 print
            • 我们将前一行存储在$prev 中。如果上一行是},当前行是{,我们会忘记上一行并读取下一行。否则,我们打印上一行如果有(这意味着我们不会在忘记的行之后打印空行)。然后我们将当前行存储到 $prev 并重复。
            • 需要END 部分来打印最后记住的行(如果有)。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2013-12-16
              • 2023-03-06
              • 2019-07-25
              • 2013-11-06
              • 1970-01-01
              • 1970-01-01
              • 2015-05-07
              相关资源
              最近更新 更多