#!/usr/bin/perl use 5.001 ; use strict ; use warnings ; # 5.014 ã§å‹•ä½œç¢ºèªæ¸ˆã¿ use autodie qw[ open ] ; use Getopt::Std ; getopts 'bd:gsnrz=~!3":' , \my%o ; use Term::ANSIColor qw/:constants color / ; $Term::ANSIColor::AUTORESET = 1 ; use Scalar::Util qw[ dualvar ] ; # <-- dualvar ã®åˆ©ç”¨ã¯ã€ã‚ã¾ã‚Šå¥½ã¾ã—ããªã„å¯èƒ½æ€§ã¯ã‚る。試ã—ã«ä½¿ã£ã¦ã¿ãŸã€‚ use FindBin qw [ $Script ] ; use Encode qw[ decode ] ; use Encode::JP ; eval "use PerlIO::gzip;1" or die "Can't import PerlIO::gzip despite -z instruction. ($Script)\n" if $o{z} ; sub main ( ) ; # å…¥åŠ›ã‚’é †æ¬¡å‡¦ç†ã™ã‚‹ sub eachFile ( $ ) ; # 引数ã§æŒ‡å®šã•ã‚ŒãŸå„ファイルを処ç†ã—ã¦ã€è¡Œæ•°ã‚’è¿”ã™ã€‚ sub lineNum ( $ ) ; # (å„ファイルã‹ã‚‰ä¸Žãˆã‚‰ã‚Œã‚‹) ファイルãƒãƒ³ãƒ‰ãƒ«ã‹ã‚‰ã€è¡Œæ•°ã‚’è¿”ã™ã€‚ sub sigint ( ) ; # Ctrl-C ãŒæŠ¼ä¸‹ã•ã‚ŒãŸæ™‚ã®å‡¦ç† sub hhmmss ( ) ; # ç¾åœ¨æ™‚刻を yyyy-mm-dd HH:MM:SS ã®å½¢ã§è¿”ã™ã€‚ sub cyc_rep ( ) ; $/ = "\r\n" if $o{r} ; #$/ = "" ; $| = 1 if $o{'!'} ; * CYAN = * BRIGHT_CYAN = * BLUE = * BRIGHT_BLUE = sub { @_ } if $o{b} ; # <-- TRICKY A LITTLE. my ($time0, $time00) = (time) x 2 ; my $cyc_sec = $o{'"'} // 10 ; # 何行毎ã«ãƒ¬ãƒãƒ¼ãƒˆã‚’発生ã•ã›ã‚‹ã‹ã€‚ my $cyc_last_line ; # my $noLineEnd = 0 ; # 行末ã®æ–‡å—ãŒæ”¹è¡Œ(æ£ç¢ºã«ã¯ $/ ) ã«ä¸€è‡´ã—ãªã‹ã£ãŸãƒ•ã‚¡ã‚¤ãƒ«ã®å€‹æ•° my $dirnum = 0 ; # ディレクトリã®å€‹æ•° my $fn ; # èªã‚“ã§ã„るファイルã®åå‰ my $FH ; # ファイルãƒãƒ³ãƒ‰ãƒ« main ; exit 0 ; sub main ( ) { my $time00 = time ; my $total_lines = 0 ; # 全ファイルã®è¡Œæ•°ã®åˆè¨ˆ @ARGV = ( '-' ) unless @ARGV ; $SIG{INT} = \& sigint ; ## \sigint $total_lines += eachFile $_ for @ARGV ; * BLUE = * BRIGHT_BLUE ; # <-- - TRICKY ! #my $fn ; # åˆè¨ˆã®é …ç›®ã§ã‚ã‚‹ã“ã¨ã‚’表ã™æ–‡å—列 $fn = (scalar @ARGV - $dirnum). " files" ; $fn .= " plus $dirnum directories" if $dirnum > 0 ; $fn = "[- $fn -]" ; out1line ( dualvar ($total_lines , -"$noLineEnd" ) , $fn , $time00 ) if @ARGV >= 2 ; # 1個ã—ã‹å…¥åŠ›ãŒç„¡ã„å ´åˆã¯å‡ºã•ãªã„。 } # å„ファイルã«å¯¾ã—ã€dualvarã§è¡Œæ•°ã¨EOF状態を返ã™ã€‚ファイルåã‹ã‚‰è¡Œæ•°ã‚’è¿”ã™é–¢æ•°ã‚’èµ·å‹•ã—ã€ãれを出力ã™ã‚‹é–¢æ•°ã‚’èµ·å‹•ã™ã‚‹ã€‚ sub eachFile ( $ ) { my $time0 = time ; $fn = $_[0] ; # ファイルãƒãƒ³ãƒ‰ãƒ©ã‚’è¨å®šã€‚"-" ãªã‚‰æ¨™æº–入力。 if ( $_[0] ne "-" ) { if ( ! $o{g} ) { open $FH , '<' , $_[0] } else { open $FH , '-|' , 'gzcat' , $_[0] ; #open $FH [ $_ ] , '-|' , 'gzcat' , $ARGV[$_] ; # open $FH, "gzcat '$ARGV[$_]' |" より良ã„ã¨æ€ã£ãŸ } } else { $FH = * STDIN } ; binmode $FH , ":gzip(gzip)" if $o{z} ; my $header = <$FH> if $o{'='} ; # <-- 一応æ„味ã¯ã‚る。-+ スイッãƒã‚ªãƒ—ションã§å¯¾å¿œã§ããªã„ã‹? my $ret = lineNum $FH ; out1line ( $ret , $fn , $time0 ) ; return $ret ; } # ファイルãƒãƒ³ãƒ‰ãƒ©ã‹ã‚‰è¡Œæ•°ã‚’è¿”ã™ã€‚ sub lineNum ( $ ) { my $last_count = $. ; my $FH = $_[0] ; my $count = 0 ; my $final_line = '' ; # 次ã®è¡Œã§ä½•ã‚‚èªã¿å–ã‚Œãªã„å ´åˆã®å¯¾ç–ã¨ã—ã¦ã€ '' を代入。 if ( -d $_[0] ) { $dirnum++ ; return dualvar (0, 'dir.') } ; $SIG{ALRM} = sub { cyc_rep ; alarm $cyc_sec } ; alarm $cyc_sec ; while ( <$FH> ) { $final_line = $_ }; $count = $. - $last_count ; # 高速化ã®ãŸã‚ã€ç›´å‰ã®ãƒ«ãƒ¼ãƒ—ã§æ•°ãˆã‚‹ã“ã¨ã¯ã‚„ã‚ãŸã€‚ alarm 0 ; #$cyc_last_line = 0 ; # <-- å ´æ‰€ã¯ã“ã“ã§è‰¯ã‹ã£ãŸã®ã ã‚ã†ã‹ #$. = 0 ; unless ( chomp $final_line ) { $noLineEnd ++ ; return dualvar $count , $count ? '-1' : '-0' } ; return dualvar $count , '' ; # <-- 改行ã§çµ‚ã‚ã£ã¦ã„ã‚Œã°ã€ç©ºæ–‡å—ã‚’æ–‡å—列コンテクストã®éƒ¨åˆ†ã«ä¸Žãˆã‚‹ã€‚ } # 出力ã™ã‚‹å„è¡Œã«ã¤ã„ã¦ã®å‡¦ç†ã€‚ sub out1line ( $$$ ) { # 引数ã¯ã€$ret , $fn , $time0 my @out ; my $lines = $_[0] + 0 ; # Util::Scalar ã«ã‚ˆã‚‹ dualvar å½¢å¼ã®å€¤ã‹ã‚‰ã€æ•°ã‚³ãƒ³ãƒ†ã‚ストã§æ•°ã‚’å–り出ã™ã€‚ $lines =~ s/(?<=\d)(?=(\d\d\d)+($|\D))/,/g if $o{3} ; # 3æ¡æ¯Žã«ã‚³ãƒ³ãƒžã§åŒºåˆ‡ã‚‹ $lines = substr ( ' ' x $o{d} . $lines , - $o{d} , $o{d} ) if $o{d} ; push @out , $lines if ! $o{'~'} ; push @out , $_[1] if ! $o{n} ; # ファイルå push @out , $lines if $ o{'~'} ; do { my $sec = time - $_[2] ; my $dt = hhmmss ; push @out , BLUE "[${sec} sec. $dt]" } if ! $o{s} ; push @out , $_[0] . '' if $_[0] ne "0" ; # dualvar ã ã‹ã‚‰ .'' ã®æ“作ã§æ–‡å—列を抽出ã™ã‚‹å¿…è¦ãŒã‚る。 print join ( "\t" , grep { $_ ne '' } @out ) , "\n" ; } # Ctrl-C ãŒæŠ¼ä¸‹ã•ã‚ŒãŸæ™‚ã®å‡¦ç† sub sigint ( ) { alarm 0 ; print STDERR YELLOW sprintf ( " [ %0.3e ]-th line in [ $fn ]", $. ) , " read by '$Script'. " . hhmmss . "\n" ; $SIG{INT} = sub { print STDERR BRIGHT_YELLOW " $. [ $fn ] " , "'$Script' " , hhmmss , "\n" ; close $FH ; exit 130 } ; alarm 1 ; my $tmp = $SIG{ALRM} ; $SIG{ALRM} = sub { $SIG{INT} = \& sigint ; $SIG{ALRM} = $tmp ; alarm $cyc_sec } ; # <-- perl ç”±æ¥ã®ãƒˆãƒ©ãƒ–ルãŒèµ·ãã¾ã›ã‚“よã†ã«ã€‚ } # ç¾åœ¨æ™‚刻を HH:MM:SS ã®å½¢ã§è¿”ã™ã€‚ sub hhmmss ( ) { my @f = @{[localtime]}[5,4,3,2,1,0] ; $f[0] += 1900 ; $f[1] += 1 ; return sprintf ( "%02u:%02u:%02u" , @f[3..5] ) ; #return sprintf ( "%04u-%02u-%02u %02u:%02u:%02u" , @f ) ; } sub cyc_rep ( ) { use FindBin '$Script' ; $| = 1 ; my $num = $. ; my $diff = ' (+' . ( $num - $cyc_last_line ) . ')' if defined $cyc_last_line ; $cyc_last_line = $num ; $num =~ s/(?<=\d)(?=(\d\d\d)+($|\D))/,/g ; # 3æ¡æ¯Žã«ã‚³ãƒ³ãƒžã§åŒºåˆ‡ã‚‹ $diff =~ s/(?<=\d)(?=(\d\d\d)+($|\D))/,/g if defined $diff ; $diff //= '' ; print STDERR GREEN $num , $diff , ":\t" , sprintf "%02d:%02d:%02d" , ( localtime )[2,1,0] ; # <-- 標準出力ã«æ›¸è¾¼ã¿ print STDERR "\t" , GREEN time - $time0 , " sec.\t($Script)" ; chomp (my $line_tmp = $_ ) ; print STDERR BLUE "\t Read Input:\t" , $line_tmp ; $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 Unix ã® wc -l ã®ä»£æ›¿ã€‚行数を出力ã™ã‚‹ã€‚ 引数ãªã©ã§æŒ‡å®šã•ã‚ŒãŸãƒ•ã‚¡ã‚¤ãƒ«ãŒã€æ”¹è¡ŒåŒºåˆ‡ã‚Šæ–‡å—ç„¡ã—ã§çµ‚了ã—ã¦ã„ãŸå ´åˆã¯-1 ã‚’å„行末ã«è¿½åŠ ã§å‡ºåŠ›ã™ã‚‹ã€‚ãŸã ã—ã€ç©ºæ–‡å—列ã§æ”¹è¡Œãªã—ã®å ´åˆã¯-0を出力ã«è¿½åŠ ã™ã‚‹ã€‚ ã“ã‚Œã¯ã€åˆ†å‰²ã•ã‚ŒãŸãƒ•ã‚¡ã‚¤ãƒ«ã®åˆè¨ˆè¡Œæ•°ã‚’計算ã—ãŸã„時ã«ä½¿ãˆã‚‹æ©Ÿèƒ½ã§ã‚る。 ãªãŠã€Ctrl+C ãŒæŠ¼ä¸‹ã•ã‚ŒãŸå ´åˆã€é€”ä¸ã®çŠ¶æ…‹ã‚’表示ã—ã¦ã€å…ƒã«æˆ»ã‚‹ã€‚ 1秒以内ã«å†ã³ã€Ctrl+C ãŒæŠ¼ä¸‹ã•ã‚ŒãŸå ´åˆã®ã¿ã€ãƒ—ãƒã‚°ãƒ©ãƒ ã¯åœæ¢ã™ã‚‹ã€‚ オプション: [行数ã®å‡ºåŠ›ã®æ•°ã¨ã—ã¦ã®æ›¸å¼] -3 ; 行数ã®å‡ºåŠ›ã«3æ¡æ¯Žã«ã‚³ãƒ³ãƒžã‚’挿入ã™ã‚‹ã€‚ -d num ; 行数を出力ã™ã‚‹åˆ—ã®å¹…を指定ã™ã‚‹ã€‚ãã—ã¦ã€å³è©°ã‚ã«ã—ã¦èªã¿ã‚„ã™ãã™ã‚‹ã€‚ [出力ã™ã‚‹ä»–ã®æƒ…å ±ã¨è‰²] -b : 色を付ã‘ãªã„ -n : å„入力を処ç†ã™ã‚‹éš›ã«ã€ãƒ•ã‚¡ã‚¤ãƒ«åや標準入力ã®åˆ¥ã‚’表示ã—ãªã„。(Number only) -s : ファイルåã¨è¡Œæ•°ã¯è¡¨ç¤ºã™ã‚‹ãŒã€æ™‚åˆ»æƒ…å ±ã¯å‡ºã•ãªã„。(Simple) -! ; 出力をãƒãƒƒãƒ•ã‚¡ã«è²¯ã‚ãªã„。 -\" num ; num秒ã”ã¨ã«ä½•è¡Œã‚’èªã¿å–ã£ãŸã‹ã‚’標準エラー出力ã«å‡ºåŠ›ã™ã‚‹ã€‚未指定ãªã‚‰10秒。0を指定ã™ã‚‹ã¨éžå‡ºåŠ›ã€‚ [入力ã®ä»•æ–¹ã®æŒ‡å®š] -= : 最åˆã®è¡Œã‚’計数対象ã¨ã—ãªã„。 -r ; 改行文å—ã‚’ "\r\n" ã«å¤‰æ›´ã€‚エクセルã‹ã‚‰ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã—ãŸæ™‚ã«ä¾¿åˆ©ã€‚(未指定ãªã‚‰ã€"\n"。) -z : 入力を gzip 圧縮ã®å½¢å¼ã¨ã—ã¦å‡¦ç†ã™ã‚‹ã€‚ -g ; 入力を gzcat コマンドを利用ã—ã¦å‡¦ç†ã™ã‚‹ã€‚-z より高速ã ãŒã€æ¨™æº–入力ã«ã¯ç¾çŠ¶ä½¿ãˆãªã„。 --help : ã“ã® $0 ã®ãƒ˜ãƒ«ãƒ—メッセージを出ã™ã€‚ perldoc -t $0 | cat ã§ã‚‚ã»ã¼åŒã˜ã€‚ --help opt : オプションã®ã¿ã®ãƒ˜ãƒ«ãƒ—を出ã™ã€‚opt以外ã§ã‚‚ options ã¨å…ˆé ãŒ1æ–‡å—以上一致ã™ã‚Œã°è‰¯ã„。 テスト: seq 10 | gzip -c | $0 # -z 指定ã§ã€€gzip 圧縮をå—ã‘å–れるã‹è©¦é¨“。 $0 <( yes ) # 上記ã®ã‚³ãƒžãƒ³ãƒ‰ã‚’実行ã™ã‚‹ã€‚Ctrl-Cを続ã‘ã¦2秒以内ã«æŠ¼ä¸‹ã™ã‚‹ã¨ã€æ¢ã¾ã‚‹ã€‚ # yes | $0 ã ã¨ã€ã†ã¾ãã„ã‹ãªã„。 # Ctrl-C ã®å—ã‘å–ã‚Šæ–¹ãŒã€ãƒ‘イプã®å‰ã®ã‚³ãƒžãƒ³ãƒ‰ã¨ # プãƒã‚»ã‚¹ç½®æ› <( ) ã¨ã§ç•°ãªã‚‹ãŸã‚。 注æ„点: * Unixコマンドã¯ã€æœ€å¾Œã«æ”¹è¡Œæ–‡å—ã§çµ‚了ã—ãªã„è¡Œã¯æ•°ãˆãªã„。 ã“ã®ã‚³ãƒžãƒ³ãƒ‰ $0 ã¯ãã®ã‚ˆã†ãªè¡Œã‚‚æ•°ãˆã‚‹ã€‚従ã£ã¦ã€ãã®å ´åˆã€æ•°ã«é•ã„ãŒå‡ºã‚‹ã‚‹ 開発上ã®ãƒ¡ãƒ¢: * 全体ã®åˆè¨ˆå€¤ã«ãŠã„ã¦ã€æ”¹è¡Œã§çµ‚ã‚らãªã‹ã£ãŸãƒ•ã‚¡ã‚¤ãƒ«ã®å€‹æ•°ã¨ã€concat ã—ãŸå ´åˆã®å·®ã¯ã¾ãŸåˆ¥ã®ãƒã‚¸ãƒƒã‚¯ã‚’ è¦ã™ã‚‹ã€‚-1 ã¾ãŸã¯ -0 を出力ã—ãŸå€¤ã®ãれらã®åˆè¨ˆã¨å…±ã«å‡ºã™ã‚ˆã†ã«ã™ã‚‹å¿…è¦ãŒã‚る。 =cut