#!/usr/bin/perl use 5.001 ; use strict ; use warnings ; use Getopt::Std ; getopts '@:?:=:c:d:f:gr,:' , \my %o ; use PerlIO::gzip ; use Term::ANSIColor qw[ :constants color ] ; $Term::ANSIColor::AUTORESET = 1 ; use autodie 'open' ; # <-- - æ„味を為ã—ã¦ã„ã‚‹ã‹ã‚’確èªã—ãŸã„。 sub cyc_rep ( ) ; sub main ( ) ; sub mainC ( ) ; sub closing ( ) ; $/ = "\r\n" if $o{r} ; $o{d} //= 1 ; # 出力ファイルã®åå‰ã«ä»˜åŠ ã™ã‚‹æ•°ã®æœ€å°ã®æ¡æ•°ã®æŒ‡å®šã€‚ my $per_cyc = $o{'@'} // 1e6 ; my ($time00, $time0) = (time) x 2 ; my $bodyname = $o{f} // 'out' ; # 出力ã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ç¾¤ã®åå‰ã¯ã€ã“ã‚Œã«ã€ãƒ”リオドã¨æ•°ã¨ãªã‚‹ã€‚ my $isep = do { $o{','} //= $ENV{isep} // "\t" ; eval qq[qq[$o{','}]] } ; # 入力ã®åŒºåˆ‡ã‚Šæ–‡å— # ã“ã“ã‹ã‚‰4個ã®å¤‰æ•°ã¯ -c ãŒæŒ‡å®šã•ã‚ŒãŸæ™‚ã«å¿…è¦ã¨ãªã‚‹ã€‚-c ãŒç„¡ã‘ã‚Œã°ä½¿ã‚ã‚Œãªã„変数。 my (%seen,%ofh) ; # ç€ç›®ã—ãŸå€¤ã‚’見ãŸã‹ã€ãã—ã¦ãã‚Œã«å¯¾å¿œã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ã®ãƒ‡ã‚¹ã‚¯ãƒªãƒ—ã‚¿ my $fc = 0 ; # ç•°ãªã‚‹æ³¨ç›®åˆ—ã®å€‹æ•° my $fn = 0 ; # 生æˆå‡ºåŠ›ãƒ•ã‚¡ã‚¤ãƒ«æ•° my $status = 0 ; # è¿”ã™ã‚³ãƒ¼ãƒ‰ã€‚Ctrl+C㧠130 ã¨ã™ã‚‹ã€‚ãªãŠã€ãƒ•ã‚¡ã‚¤ãƒ«ã‚ªãƒ¼ãƒ—ンã®ã‚¨ãƒ©ãƒ¼ã¯ãŠãらã255ã¨ãªã‚‹ã€‚ unless ( $o{c} ) { main } else { mainC ; closing } exit ; sub main ( ) { my @ofh ; my $cols = 0 ; # 列ã®å€‹æ•°ã‚’æ ¼ç´ã€‚最åˆã®è¡Œã‚’èªã¿å–ã£ãŸæ™‚点ã§ç¢ºå®šã€‚ my $layer = $o{g} ? '>:gzip' : '>' ; # "レイヤー" ã®æŒ‡å®š my $empty = $o{e} // '?' ; # 列ãŒè¶³ã‚Šãªã„å ´åˆã«æ ¼ç´ã™ã‚‹æ–‡å—列 while ( <> ) { chomp ; my @F = split /$isep/ , $_ , $cols || -1 ; # <-- é•·ã„ã‚‚ã®ã‚’æ¨ã¦ã‚‹ã“ã¨ã®å†…容ã«ã™ã‚‹ãŸã‚ || を使ã†ã€‚ if ($.==1) { for ( @F ){ $cols ++ ; my $num = sprintf "%0$o{d}d" , $cols ; $num .= '.gz' if $o{g} ; open my $ofh , $layer , "$bodyname.$num" or die $! ; push @ofh , $ofh ; } } print {$_} shift @F // $empty , "\n" for @ofh ; # <-- ãã‚Œãžã‚Œã®ãƒ•ã‚¡ã‚¤ãƒ«ã«æ›¸ã込㿠cyc_rep if $per_cyc && $. % $per_cyc == 0 ; } grep { close $_ } @ofh ; } sub mainC ( ) { my $layer = $o{g} ? '>:gzip' : '>' ; # 出力ã®IOレイヤーã®æŒ‡å®š my $tail = $o{g} ? '.gz' : '' ; # 出力ファイルåã®æœ«å°¾ my $header = <> if $o{'='} ; my $loc = do { $o{c}//=1 ; $o{c} >= 0 ? $o{c} - 1 : $o{c} } ; # ã©ã®åˆ—ã‚’å–り出ã™ã‹ my $maxfc = $o{m} // 200 ; my $residual = 'residual' ; # 最大個数ã«é”ã—ãŸæ™‚ã«ä½¿ã†æ–‡å—列<-- - ã“ã®æ–‡å—列ã¯æŒ‡å®šå¯èƒ½ã¨ã—ãŸã„。 $SIG{INT} = sub { $status = 130 ; closing } ; while ( <> ) { chomp ; my $id = ( split /$isep/, $_ , -1 ) [ $loc ] // 'undef' ; # <-- - ã“ã®undef ã® å ´åˆã®æ–‡å—列ã¯æŒ‡å®šå¯èƒ½ã¨ã—ãŸã„。 unless ( $seen{$id} ++ ) { $fc ++ ; if ( $fc >= $maxfc ) { print " " x 40 . "$fc $id\r" ; $id = $residual ; } unless ( exists $ofh{$id} ) { open my $ofh , $layer , "$bodyname$id$tail" ; $fn ++ ; $ofh{ $id } = $ofh ; print {$ofh} $header if defined $header ; } } my $ofh = exists $ofh{$id} ? $ofh { $id } : $ofh { $residual } ; # $ofh{$id}//$ofh{$residual}ã¯ã†ã¾ãã„ã‹ãšã€‚ print {$ofh} $_ . "\n" ; cyc_rep if $per_cyc && $. % $per_cyc == 0 ; } } sub closing ( ) { use FindBin '$Script' ; my $num = $. ; $num =~ s/(?<=\d)(?=(\d\d\d)+($|\D))/,/g ; # 3æ¡æ¯Žã«ã‚³ãƒ³ãƒžã§åŒºåˆ‡ã‚‹ my $sec = time - $time00 ; print STDERR CYAN "$num lines processed. $fc different remarked column values. $fn output files. ($Script ; $sec sec.)" ; close $_ for values %ofh ; exit $status ; } sub cyc_rep ( ) { use FindBin '$Script' ; $| = 1 ; my $num = $. ; $num =~ s/(?<=\d)(?=(\d\d\d)+($|\D))/,/g ; # 3æ¡æ¯Žã«ã‚³ãƒ³ãƒžã§åŒºåˆ‡ã‚‹ print STDERR GREEN $num , ":\t" , sprintf "%02d:%02d:%02d" , ( localtime )[2,1,0] ; # <-- 標準出力ã«æ›¸è¾¼ã¿ print STDERR "\t" , GREEN time - $time0 , " sec.\t($Script)" ; print STDERR "\t" , BLUE $_ ; $time0 = time ; print STDERR "\n" ; } ## ヘルプã®æ‰±ã„ 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 -f out < input # 表形å¼ã®å…¥åŠ›ã‚’列ã”ã¨ã«ã€ç¸¦ã«ã°ã‚‰ã°ã‚‰ã®ãƒ•ã‚¡ã‚¤ãƒ«ã«ã™ã‚‹ã€‚ $0 -c colnum -f out < input # 注目列ã®å€¤ã”ã¨ã«åˆ†é¡žã—ã¦ã€ã°ã‚‰ã°ã‚‰ã®ãƒ•ã‚¡ã‚¤ãƒ«ã¸ã€‚ 動作 : 入力ファイル file をタブ区切りã®tsvファイルã§ã‚ã‚‹ã¨è¦‹ãªã™ã€‚ -c ãŒç„¡ã„å ´åˆ ã«ã¯ã€ç¬¬n列ã®å€¤ã‚’å…ˆé è¡Œã‹ã‚‰æœ€çµ‚è¡Œã¾ã§ã€file.n ã®ã‚ˆã†ãªãƒ•ã‚¡ã‚¤ãƒ«åã§ä¿å˜ã™ã‚‹ã€‚ -c ãŒã‚ã‚‹å ´åˆã¯ã€ãã®æ•°ã®ä½ç½®ã®åˆ—ã®å€¤ã«å¿œã˜ã¦ã€å…¥åŠ›å„行を分類ã—(横分割ã—)ã€å„ファイルã«æ ¼ç´ã€‚ オプション: -d num : æ¡æ•°ã‚’指定。生æˆã•ã‚Œã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ã®åå‰ã«ä½¿ã‚れる数をゼãƒåŸ‹ã‚ã«ã™ã‚‹ã¨ãã«ä¾¿åˆ©ã€‚ -f str : 出力ã®ãƒ•ã‚¡ã‚¤ãƒ«ç¾¤ã®å…±é€šã™ã‚‹éƒ¨åˆ†ã®æ–‡å—列を指定ã™ã‚‹ã€‚未指定ãªã‚‰ "out"。 -g ; gzip å½¢å¼ã§å‡ºåŠ›ã™ã‚‹ã€‚ -m num : 出力ã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ã®å€‹æ•°ã®è¨å®šã€‚未指定ãªã‚‰ 200 。 -, str : 入力ã®åŒºåˆ‡ã‚Šæ–‡å—ã®æŒ‡å®šã€‚未指定ãªã‚‰ã€\t ã¨ãªã‚‹ã€‚ -r : 入力ã®æ”¹è¡Œã‚³ãƒ¼ãƒ‰ãŒã€€\r\n ã§ã‚ã‚‹ã“ã¨ã®æŒ‡å®šã€‚ -@ num : 何行ã”ã¨ã«é€”ä¸ã®ãƒ¬ãƒãƒ¼ãƒˆã‚’è¿”ã™ã‹ã‚’指定ã™ã‚‹ã€‚未指定ãªã‚‰10万行。 -'?' str ; 列ãŒå°‘ãªã™ãŽã‚‹è¡ŒãŒã‚ã£ãŸå ´åˆã«ã€å‡ºåŠ›å…ˆã«æ ¼ç´ã™ã‚‹æ–‡å—を指定。未指定ãªã‚‰?。 -= ; å…ˆé ãŒãƒ˜ãƒƒãƒ€è¡Œã§å§‹ã¾ã‚‹ã¨ä»®å®šã™ã‚‹ã€‚出力ã®å„ファイルã®ä¸€è¡Œç›®ãŒå…¥åŠ›ãƒ•ã‚¡ã‚¤ãƒ«ã®ä¸€è¡Œç›®ã¨ãªã‚‹ã€‚(-cを使ã†æ™‚挙動ãŒå¤‰ã‚る。) --help : ã“ã® $0 ã®ãƒ˜ãƒ«ãƒ—メッセージを出ã™ã€‚ perldoc -t $0 | cat ã§ã‚‚ã»ã¼åŒã˜ã€‚ --help opt : オプションã®ã¿ã®ãƒ˜ãƒ«ãƒ—を出ã™ã€‚opt以外ã§ã‚‚ options ã¨å…ˆé ãŒ1æ–‡å—以上一致ã™ã‚Œã°è‰¯ã„。 環境変数 : $isep : 入力ã«ã¤ã„ã¦ã®åŒºåˆ‡ã‚Šæ–‡å—ã®æŒ‡å®šã€‚未指定ãªã‚‰ã€ã‚¿ãƒ–æ–‡å—。 注æ„点 : åŒæ™‚ã«å¤šæ•°ã®æ›¸è¾¼ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é–‹ãã®ã§ã€ulimit -n ã§ãã®æ•°ã‚’確èªã™ã‚‹ã“ã¨ã€‚ =cut