#!/usr/bin/perl

use 5.001 ; 
use strict ; 
use warnings; 
use Getopt::Std ; 

getopts ':i:c:t=~^' , \my%o ;  

sub init ( ) ;
sub main ( ) ;
sub procOut ( @ ) ;

my @C ; # 指定する列の集合
my $flagW = 0 ; # 行全体を対象とするかどうか

init ; 
main ; 
exit 0 ;

sub init ( ) { 

    $o{i} //= 1 ; # 同じ列が何個続いたら出力をするか。以前は、2行以上続いたら、出力しようとしていた。
    $o{'~'} = defined $o{'~'} ? 1 : 0 ;


    if ( $o{'='} ) {
        my $head = <> ;
        print $o{':'} ? "=:\t$head" : $head ; 
        print "\n" unless $o{t} ;
        $. = 0 ;  # <-- 行番号を一旦リセット。何番目のデータ化を出力したいため。
    }

    if ( defined $o{c} and $o{c} ne '0' ) 
    {
        @C = eval $o{c} ; # -c 1..5,8 とあれば、1,2,3,4,5,8 という配列に展開される。逆順には対応できないが。
        grep { $_ -- if $_ > 0 } @C ;
        #print $_ , ", " for @C ; 
    }
    else 
    { 
        $flagW = 1 ; 
        @C = ( 0 ) ; 
    }

}


sub main ( ) { 
    my $inarow ;   # 何行続いたかを計数。
    my @out ;      # 出力する内容。一行毎。 
    my $prvFC ;  # 直前の行の、各フィールドの内容

    while ( <> ) { 
        chomp ;
        my @F = $flagW ? ( $_ ) : split /\t/, $_ , -1 ; 
        
        my $FC = join "\t" , @F [ @C ] ;    # <-- - わざわざ join しない良いやり方があるはずではある。

        if ( defined $prvFC ) 
        { 
            if ( $FC eq $prvFC )
            { 
                push @out , $o{':'} ? "$.:\t$_" : $_  ;
                $inarow ++ ;
            }
            else 
            { 
                procOut @out ; 
                @out = $o{':'} ? "$.:\t$_" : $_  ; 
                $inarow = 1 ;
            }
        }

        $prvFC = $FC ; 
        #print "\$inarow=$inarow\n" ;
    }

    procOut ( @out ) ;
} 

sub procOut ( @ ) { 
    return if scalar @_ == 0 ; # <-- -  冗長であるはず。
    return if scalar @_ < $o{i} xor $o{'~'} ; # 指定連続個数が続いていない場合は出力しない。
    #print "." . scalar @_ ."\n" ;
    if ( $o{'^'} ) { 
        $_ = "\t" . $_ for @_ ; 
        $_[0] = "*" . $_[0] ;
    }
    print $_ , "\n" for @_ ;      # @out の中身を表示する。
    print "\n" unless $o{t} ;           # 空行を出力する場合は、そうする。
}

## ヘルプの扱い
sub VERSION_MESSAGE {}
sub HELP_MESSAGE {
    use FindBin qw[ $Script ] ; 
    $ARGV[1] //= '' ;
    open my $FH , '<' , $0 ;
    while(<$FH>){
        s/\$0/$Script/g ;
        print $_ if s/^=head1// .. s/^=cut// and $ARGV[1] =~ /^o(p(t(i(o(ns?)?)?)?)?)?$/i ? m/^\s+\-/ : 1;
    }
    close $FH ;
    exit 0 ;
}

=encoding utf8 

=head1

 $0  

  前後の行で着目列(複数可)が同じであればつながったグループと見なす。
  各グループが指定した個数以上の行を持てば、出力する。
  グループの前後に空白行を -t の指定が無い限り、挿入する。


使用例 : 

  $0 -c 1..3 -i 5 < datafile 
   # 1列目から3列目について、同じ値が5回以上続けて出現した場合に、
   # 空行で挟んでそれを出力。

オプション: 

 -c nums : どの列の組みあわせが変わったかどうかに着目するか、指定。, や .. を使う。未指定なら全列指定と同様。
 -i num : 注目した列がnum個以上続いた行だけを出力。未指定ならば、1を指定したことと同等。
 -~     ; 条件を反転する。num個以上という条件を反転して、num個未満とする。

 -t     : グループ間に、空文字列行を挿入しない。(tight)
 -=     : 先頭の行はそのまま出力。
 -:     : 何番目のデータであるかも表示する。

=cut



