#!/Users/toshiyuki-shimono/.plenv/versions/5.32.1/bin/perl5.32.1 use 5.014 ; use strict ; use warnings ; use Scalar::Util qw/looks_like_number/; # 5.7 ~ use Getopt::Std; getopts '::^:~=+:,:@:0:1:d:i:qvm:' , \my %o ; use Term::ANSIColor qw/:constants color/; $Term::ANSIColor::AUTORESET = 1 ;# v5.6 ~ #use utf8 ; my $isep = $o{i} // "\t" ; # 入力ã®åŒºåˆ‡ã‚Šæ–‡å— my $oemp = $o{'0'} // 0 ; # 出力ã®ã‚»ãƒ«ãŒæœªå®šç¾©å€¤ã®å ´åˆã«ä»£ã‚ã‚Šã«å‡ºåŠ›ã™ã‚‹æ–‡å—列 my $sec = $o{'@'} // 10 ; # 何秒ã”ã¨ã«å‡¦ç†çŠ¶æ…‹ã‚’出力ã™ã‚‹ã‹ã€‚ my $addC ; # ã‚ã‚‹åˆ—ã‚’åŠ ç®—ã™ã‚‹å ´åˆã®åˆ—ã®æŒ‡å®š my $t00 ; # 表ã®å·¦ä¸Šéš…ã«è¼‰ã›ã‚‹æ–‡å—列 my %ax2 ; # ã‚ーã¯æ¨ªè»¸ã®é …ç›®åã¨ãªã‚‹ã€‚ my %C ; # セルã®å€¤ my %Cc ; # 1件を1個ã¨æ•°ãˆã‚‹ã€‚ my %Ce ; # 空文å—列ã®å€‹æ•°ã‚’æ•°ãˆã‚‹ã€‚ $o{','} //= 3 ; # 何æ¡ã”ã¨ã«åŒºåˆ‡ã‚‹ã‹ $o{d} //= 0 ; # å„セルを何æ¡ã®ã‚¹ãƒšãƒ¼ã‚¹ã§å³è©°ã«ã™ã‚‹ã‹ã€‚ $SIG{ALRM} = sub { (my $n=$.) =~ s/(?<=\d)(?=(\d\d\d)+($|\D))/,/g ; # 3æ¡ã”ã¨ã«åŒºåˆ‡ã‚‹ã€‚ print STDERR GREEN "$n lines read. " , scalar localtime , " " , RESET '' ; alarm $sec } ; my $IntFirst = sub { &{ $SIG{ALRM} } ; print STDERR BRIGHT_RED 'Do you want to get the halfway result? Then type Ctrl + C again within 2 seconds. '. "\n" . 'Really want to Quit? Then press Ctrl + "\" or Ctrl + Yen-Mark. (Ctrl+Z may be what you want.) ' . RESET "\n" ; $SIG{INT} = sub { select *STDERR ; & Output ; select *STDOUT ; return } ; sleep 2 ; return ; } ; $SIG{INT} = $IntFirst ; & Init ; & Input ; & Output ; exit 0 ; sub Init { * CYAN = * GREEN = sub { @_ } if $o{q} ; # -q ã«ã‚ˆã‚Šç€è‰²ã‚³ãƒžãƒ³ãƒ‰ã‚’無効化ã™ã‚‹ã€‚ $addC = $o{'+'} > 0 ? $o{'+'} - 1 : $o{'+'} if $o{'+'} ; $addC = $o{'^'} > 0 ? $o{'^'} - 1 : $o{'^'} if $o{'^'} ; } sub Input { $t00= $o{'='}? <> : "X1\tX2" ; chomp $t00; $t00 =~ s{\t}{*}g ; $t00 = $o{1} if defined $o{1} ; # ) { my $t = quotemeta $o{1} ; $t00 =~ s/.*/$t/ } #s/.*\t/\Q$o{1}\E/ if defined $o{1} ; alarm $sec ; while(<>){ chomp; my @F = split /$isep/o , $_ , -1 ; #($addC//2)+1 ; #3列目以é™ã¯é€£çµã™ã‚‹ã€‚ -x ã¨çµ„ã¿åˆã‚ã›ã¦ä½¿ã†ã¨ã‚ˆã„ã‹ã‚‚。 my $add = defined $addC ? splice ( @F, $addC , 1 ) : 1 ; # åŠ ç®—ã™ã‚‹å ´åˆã®å‡¦ç† grep { $_ //= 'undef' } @F[0,1] ; $ax2 { $F[1] } ++ ; $o{'^'} and $C { $F[0] } { $F[1] } = $add or $C { $F[0] } { $F[1] } += $add || 0 ; next unless $o{v} ; $Ce { $F[0] } { $F[1] } ++ if $add eq '' ; $Cc { $F[0] } { $F[1] } ++ if $o{3} ; } } sub Output { cellMult ( \%C, $o{m} ) if defined $o{m} ; # -x ã®ã‚ªãƒ—ションã§ã€æŒ‡å®šã•ã‚ŒãŸæ•°ã‚’ã‹ã‘ç®—ã—ã¦ã€æ•´æ•°éƒ¨åˆ†ã‚’å–り出ã™ã€‚ #insComma ( \%C, 3 ) if defined $o{','} ; # -, ã®ã‚ªãƒ—ションãŒã‚ã‚Œã°ã€æ•°å€¤ã«3æ¡ã”ã¨ã«ã‚³ãƒ³ãƒžã‚’挿入 # 一番目ã®ã‚¯ãƒã‚¹è¡¨ã‚’表示 showMat( \%C , $t00 ) ; #return if !$o{3} ; # -v ãŒæŒ‡å®šã—ã¦ã„ã‚‹ã‹ã©ã†ã‹ã§ç•°ãªã‚‹ã‚¯ãƒã‚¹è¡¨ã‚’表示ã™ã‚‹ã€‚ if ( $o{v} ) { print "\n" ; showMat( \%Cc , "items" ) ; # カウント対象ã¨ãªã£ãŸã™ã¹ã¦ã®è¡Œæ•° print "\n" ; showMat( \%Ce , "empties" ) ; # 空文å—列ãŒã„ãã¤å‡ºç¾ã—ãŸã‹ } $SIG{INT} = $IntFirst # my %Cv ; for my$i(@a1){for my$j(@a2){$Cv{$i}{$j}=($Cc{$i}{$j}//0)-($Ce{$i}{$j}//0)}} } sub StrNumSort ( @ ) { +( sort { $a cmp $b } grep { ! looks_like_number ($_) } @_ ) , ( sort { $a <=> $b } grep { looks_like_number ($_) } @_ ) ; } sub showMat ( $$ ) { my ($C,$h11) = @_ ; # セル, 縦軸, 横軸, 出力表ã®å·¦ä¸Šã®æ–‡å—列 my @a1 = StrNumSort ( keys %{$C} ) ; # 縦軸ã®å„é …ç›®å my @a2 = StrNumSort ( keys %ax2 ) ; # 横軸ã®å„é …ç›®å if ( defined $o{':'} ) { @a1 = () ; # リセット open my $FH , '<' , $o{':'} or die ; while ( <$FH> ){ chomp ; push @a1 , $_ } } if ( ! $o{'~'} ) { print CYAN "$h11\t" , GREEN join("\t",@a2 ),"\n" ; # 出力ã®1行目 for my $i ( @a1 ) { print GREEN $i, "\t" ; # 出力ã®1列目 print join ( "\t" , map { sprintf "%$o{d}s", insComma( $C->{$i}{$_}//$oemp , $o{','} ) } @a2 ) , "\n" ; } } else { print CYAN "$h11\t" , GREEN join("\t",@a1 ),"\n" ; # 出力ã®1行目 for my $i ( @a2 ) { print GREEN $i, "\t" ; # 出力ã®1列目 #print join ( "\t" , map { $C -> { $_ }{ $i } // $oemp } @a1 ) , "\n" ; print join ( "\t" , map { sprintf "%$o{d}s", insComma ( $C->{$_}{$i}//$oemp , $o{','} ) } @a1 ) , "\n" ; } } } sub cellMult ( $$ ) { for my $i ( keys %{ $_[0] } ) { for my $j ( keys %{ ($_[0]) -> {$i} } ) { #$_[0]->{$i}{$j} = defined $_[0]->{$i}{$j} ? int ( $_[0]->{$i}{$j} * $_[1] ) . "." : '' ; $_[0]->{$i}{$j} = int ( $_[0]->{$i}{$j} * $_[1] ) . "." ; } } } sub insComma ( $$ ) { return $_[0] if "0" eq ( $o{','} // '' ) ; (my $tmp = $_[0]) =~ s/(?<=\d)(?=(\d{$_[1]})+($|\D))/,/g ; # 3æ¡ã”ã¨ã«åŒºåˆ‡ã‚‹ã€‚ return $tmp } ## ヘルプã®æ‰±ã„ sub VERSION_MESSAGE {print "1.01\n" ;} 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 NAME crosstable -- Produce the crosstable from the 2 column data. Can also sum up a additional column by -3 switch option. 2列ã®ãƒ‡ãƒ¼ã‚¿ã‚’度数を数ãˆã¦ã€ã‚¯ãƒã‚¹ãƒ†ãƒ¼ãƒ–ルã«ã™ã‚‹ã€‚ Count the numbers of the frequencies of the combination of the 2 columns, and produce crosstable. オプション : -i REGEX : 区切り文å—ã®æŒ‡å®šã€‚コンマ , ãªã©ã«å¤‰æ›´ãŒå¯èƒ½ã€‚未指定ãªã‚‰ã‚¿ãƒ–æ–‡å—。Specify the delimiter. Default : tab -~ : 出力表ã®ã€ç¸¦è»¸ã¨æ¨ªè»¸ã‚’å転ã™ã‚‹ã€‚ (Transpose the output table btw. vertical and horizontal axis.) -= : 入力ã®1行目を列åã®ä¸¦ã³ã¨è¦‹ãªã—ã€ãƒ‡ãƒ¼ã‚¿ã®å€¤ã¨ã¯æ‰±ã‚ãªã„。2行目ã‹ã‚‰ã‚’åŠ ç®—å¯¾è±¡ã®ãƒ‡ãƒ¼ã‚¿ã¨ã—ã¦æ‰±ã†ã€‚(Skip the 1st input line.) -1 str ; 出力ã®1è¡Œ1列目ã«å…¥ã‚Œã‚‹æ–‡å—列ã®æŒ‡å®šã€‚出力ã®ãƒ¬ã‚¤ã‚¢ã‚¦ãƒˆã‚’見やã™ãã®ã«ã‚‚便利。 空文å—列ã®æŒ‡å®šã«ã¯ -1 '' ã¨ã™ã‚‹ã€‚ -+ N : N列目を残りã®å…ˆé 2列ã®å€¤ã®çµ„åˆã›ã”ã¨ã«é›†è¨ˆã—ãŸå€¤ã‚’出力ã™ã‚‹ã€‚Nã¯1始ã¾ã‚Š(Sum N-th column along the rest 2 first columns.) -^ N : 実際ã¯ãŠãらã -\^ 㧠Nを指定。N列目ã®å€¤ã‚’足ã™ã®ã§ã¯ãªããŸã 書ã込む。実験的ãªå®Ÿè£…。 -@ N : N 秒ã”ã¨ã«ï¼Œä½•è¡Œã‚’èªã‚“ã ã‹ã‚’å ±å‘Šã™ã‚‹ã€‚ Report how many have read every N seconds. -, N : 出力表ã®å„セルã®å€¤ã‚’Næ¡ã”ã¨ã«ã‚³ãƒ³ãƒžã§åŒºåˆ‡ã‚‰ãªã„。 Put comma(,) in the numbers by every N digits, such as 12,345,678. -, 0 : 出力表ã®å„セルã®å€¤ã‚’3æ¡ã”ã¨ã«ã‚³ãƒ³ãƒžã§åŒºåˆ‡ã‚‰ãªã„。Not Put comma(,) in the numbers such as 12,345,678. -m N : 出力表ã«ãŠã„ã¦ã€N ã‚’ã‹ã‘ç®—ã—ãŸæ•°ã®æ•´æ•°éƒ¨ã‚’表示ã™ã‚‹ã€‚(Multiply number and take Integer part. E.g. N=1e-5) -d N : 出力ã®å„セルã«ãŠã„ã¦ã€ä½•æ¡ã§å³è©°ã‚ã«ã™ã‚‹ã‹ã€‚å·¦å´ã‚’空白文å—ã§Næ¡ã«ãªã‚‹ã¾ã§ã¯åŸ‹ã‚る。 -0 STR : 出力表ã§åŸ‹ã¾ã‚‰ãªã„セルã«åŸ‹ã‚る値。未指定ãªã‚‰ 0。The value to be replaced on the unfilled output table cell. -v : -+ ãŒæŒ‡å®šã•ã‚ŒãŸå ´åˆã«ä»–ã®æœ‰ç”¨ãªæƒ…å ±ã‚‚å‡ºåŠ› (個数ã€ç©ºæ–‡å—列) Other entailing information. -q : 色を出ã•ãªã„よã†ã«ã™ã‚‹ã€‚ No color by ANSI color. -: FILE : 縦軸( -~ 指定ãªã‚‰æ¨ªè»¸ã§) 集計ã•ã‚Œã‚‹ã¹ãé …ç›®(æ–‡å—列)を指定ã™ã‚‹ã€‚FILEã®ä¸èº«ã«æ”¹è¡ŒåŒºåˆ‡ã‚Šã§æ ¼ç´ã•ã‚Œã¦ã„ã‚‹ã¨ã™ã‚‹ã€‚ Ctrl+C ã«é–¢ã—㦠: Try the following : $0 <( yes 1 ) # This is a little different from " yes 1 | $0 " because not only "$0" but also "yes 1" stops by Ctrl +C. 関連ã™ã‚‹ã‚³ãƒžãƒ³ãƒ‰ : keyvalues 開発上ã®ãƒ¡ãƒ¢ : * 縦軸ã¨æ¨ªè»¸ã®ãã‚Œãžã‚Œã®è¡¨ç¤ºé †åºã‚’豊富ã«ã—ã¦ã‚‚良ã•ãã†ã€‚ * オプションスイッãƒãŒ10個を超ãˆãŸã®ã§ã€ã†ã¾ãæ•´ç†ã—ãŸã„。 =cut