#! /usr/local/bin/perl -w # # clgrep - ChangeLog grep # # Copyright (C) 2000 Satoru Takabayashi # All rights reserved. # This is free software with ABSOLUTELY NO WARRANTY. # # You can redistribute it and/or modify it under the terms of # the GNU General Public License version 2. # use strict; use FileHandle; use Getopt::Long; my $opt_icase; my $opt_sort; my $opt_stat; Getopt::Long::Configure('bundling'); GetOptions( 'i|ignore-case' => \$opt_icase, 'p|sort-by-page' => \$opt_sort, 's|statistics' => \$opt_stat, ); if (@ARGV == 0) { print "usage: logrep [options] [file]...\n"; print " -i, ignore case distinctions.\n"; print " -p, sort by page.\n"; print " -s, show stat instead of doing grep.\n"; } elsif ($opt_stat) { show_stat(@ARGV); } else { my $pattern = shift @ARGV; $pattern = "(?i)" . $pattern if $opt_icase; my @matched = do_grep($pattern, @ARGV); if ($opt_sort) { @matched = sort_by_page(@matched); } print @matched; } sub show_stat { my (@fnames) = @_; my %stat; for my $fname (@fnames) { my $fh = new FileHandle; $fh->open($fname) || die "$fname: $!"; while (<$fh>) { if (/^\t\* (.+?)(?: \(|:)/) { my $title = $1; $stat{$title}++; # memo count } } } for my $title (sort {$stat{$b} <=> $stat{$a}} keys %stat) { printf "%8d %s\n", $stat{$title}, $title; } } sub do_grep { my ($pattern, @fnames) = @_; $/ = ''; if (@fnames == 0) { push @fnames, "-"; # STDIN } my @matched = (); for my $fname (@fnames) { my $fh = new FileHandle; $fh->open($fname) || die "$fname: $!"; while (<$fh>) { my $string_for_search = $_; # Remove TAB at the beginning. $string_for_search =~ s/^\t//mg; # Remove LF at the end of a line if the line is terminated with # a Japanese character encoded in EUC-JP. $string_for_search =~ s/([\xa1-\xfe])\n/$1/mg; # Concatenate lines. $string_for_search =~ s/\n/ /g; if ($string_for_search =~ /$pattern/) { push @matched, $_; } } } return @matched; } sub sort_by_page { my @logs = @_; return map { $_->[0]; } sort { $a->[1] <=> $b->[1]; } map { if (/^ \* .*?\(pp?\.(\d+)/) { [ $_, $1 ]; } else { [ $_, 0 ]; } } @logs; }