首页 文章

打印两个图案(BEGIN和END)之间的最小线条组,包括这两个图案的线条[关闭]

提问于
浏览
0

输入文件

aaa
Any--END--Pattern
bbb
ANY--BEGIN--PATTERN
ccc                   # do not print
ANY--BEGIN--PATTERN   # print 1
ddd                   # print 2
Any--END--Pattern     # print 3
eee
fff
ANY--BEGIN--PATTERN   # print 4
ggg                   # print 5
Any--END--Pattern     # print 6
hhh                   # print 7
Any--END--Pattern     # print 8
iii                   # do not print
ANY--BEGIN--PATTERN
jjj

想要输出

ANY--BEGIN--PATTERN   # print 1
ddd                   # print 2
Any--END--Pattern     # print 3
ANY--BEGIN--PATTERN   # print 4
ggg                   # print 5
Any--END--Pattern     # print 6
hhh                   # print 7
Any--END--Pattern     # print 8

注意事项

  • 从当前 Any--END--Pattern 之前的最新 ANY--BEGIN--PATTERN 打印 .

  • 打印到最后 Any--END--Pattern 如果没有 ANY--BEGIN--PATTERN 见面 .

许多类似的问题,但无法找到这个问题的答案

我从这些问题中测试的答案打印了行 ccc 和/或行 iii ...或者不打印具有 BEGINEND 模式的行 . 我的几次尝试都有这些相同的缺点和缺陷 .

我们可以编写十行脚本,但我确信有一个优雅的单行命令解决了这个问题,但我找不到它 . 因此,我认为这可能是一个很好的问题;-)

我想知道使用 sedawkperl 或者类似Unix的系统上任何其他可用工具的技巧是什么 . 请提供一个小命令行使用:bashgrepsedawkperl或您认为的任何其他工具...


编辑:

只是为了从Sundeep的注释中强调简单的命令行,通过反转输入文件来简化问题:

tac input.txt | sed -n '/END/,/BEGIN/p' | tac

但是这个命令行也会打印出来
(对于寻找类似问题的其他用户,可能不会发生这种情况)

aaa
Any--END--Pattern
ANY--BEGIN--PATTERN   # print 1
ddd                   # print 2
Any--END--Pattern     # print 3
ANY--BEGIN--PATTERN   # print 4
ggg                   # print 5
Any--END--Pattern     # print 6
hhh                   # print 7
Any--END--Pattern     # print 8

(此答案在此C编码规则中使用)

3 回答

  • 6

    awk 救援!

    $ awk '/BEGIN/{c=0; b=1} 
                  {a[c++]=$0} 
          b&&/END/{for(i=0;i<c;i++) print a[i]; delete a; c=0}' file
    
    ANY--BEGIN--PATTERN   # print 1
    ddd                   # print 2
    Any--END--Pattern     # print 3
    ANY--BEGIN--PATTERN   # print 4
    ggg                   # print 5
    Any--END--Pattern     # print 6
    hhh                   # print 7
    Any--END--Pattern     # print 8
    
  • 1

    Perl救援!

    #!/usr/bin/perl
    use warnings;
    use strict;
    
    my $last_end;
    my @buffer;
    while (<>) {
        if (/BEGIN/) {
    
            print @buffer[ 0 .. $last_end ] if defined $last_end;
    
            @buffer = $_;
            undef $last_end;
            next;
        }
        $last_end = @buffer if @buffer && /END/;
        push @buffer, $_ if @buffer;
    }
    

    @buffer 累积来自BEGIN的行, $last_end 指向缓冲区中的最后一个END,这样就可以丢弃不在END中结束的累积行 .

    作为单线(但为什么?):

    perl -ne 'defined $l && print(@B[0..$l]), (@B, $l) = $_, next if /BEGIN/; $l=@B if @B && /END/; push @B, $_ if @B' file
    
  • 1

    这应该适用于sed

    sed '$b1;/BEGIN/{:1;x;s/\(BEGIN.*END[^\n]*\).*/\1/;t;x;h};H;d' file
    

相关问题