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

oli*_*bre 0 bash shell perl awk sed

输入文件

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
Run Code Online (Sandbox Code Playgroud)

想要输出

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
Run Code Online (Sandbox Code Playgroud)

笔记

  • ANY--BEGIN--PATTERN当前的最新版本开始打印Any--END--Pattern.
  • Any--END--Pattern如果没有ANY--BEGIN--PATTERN见面,打印到最后.

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

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

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

我不知道是从使用的招数sed,awk,perl或其他任何可用的工具,容易对我们的类Unix系统.请使用:,,,,或您认为的任何其他工具提供一个小命令行...


编辑:

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

tac input.txt | sed -n '/END/,/BEGIN/p' | tac
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

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

cho*_*oba 6

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;
}
Run Code Online (Sandbox Code Playgroud)

@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
Run Code Online (Sandbox Code Playgroud)

  • @simbabque:更新;-) (3认同)