
% ./kwicgrep.pl '大喜び' tweets.csv _や器からタレや肉まで始終絶賛、[大喜び]でした。両親は国立新美術館をみ_ _がとうございました。とらちゃん[大喜び]でした。またご機嫌とらちゃんと_ _はサンタさんからのプレゼントに[大喜び]。「サンタさんもらった」「だい_ 白優勝! うちの白オタマトーンも[大喜び](うそ)"______________________ _ーダーに登録してもらえると私が[大喜び]です。"________________________
% ./kwicgrep.pl -s l '大喜び' tweets.csv _はサンタさんからのプレゼントに[大喜び]。「サンタさんもらった」「だい_ _がとうございました。とらちゃん[大喜び]でした。またご機嫌とらちゃんと_ _や器からタレや肉まで始終絶賛、[大喜び]でした。両親は国立新美術館をみ_ _ーダーに登録してもらえると私が[大喜び]です。"________________________ 白優勝! うちの白オタマトーンも[大喜び](うそ)"______________________
% ./kwicgrep.pl -s l 'enabled' /usr/share/doc/bash/bash.html | head ll option in the list will be [enabled] before_______________________ __________________________are [enabled], non-zero otherwise. When se ble Completion</B> above) are [enabled]._____________________________ <B>Pathname Expansion</B> are [enabled]._____________________________ _____________<I>names</I> are [enabled]. For example, to use the____ ro if all <I>optnames</I> are [enabled]; non-zero____________________ ___________________________If [enabled], history expansion will be pe _____________shell option, if [enabled], causes the shell to attempt _____________________Names of [enabled] shell builtins.______________ ____A colon-separated list of [enabled] shell options. Each word in_
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use Encode;
use open ':utf8';
binmode STDOUT, ":utf8";
binmode STDIN, ":utf8";
use Getopt::Long;
my $term_width = 70;
my $sort_lr_context = ""; # for sort
my $reverse_mode = 0; # for sort
GetOptions (
'width=s' => \$term_width,
"sort=s" => \$sort_lr_context,
"reverse" => \$reverse_mode,
);
my $key = shift @ARGV;
$key = Encode::decode_utf8($key) if not utf8::is_utf8($key);
my ($dummy, $klen) = get_first_n_hkchars($key, 100);
my $context_width = int(($term_width - ($klen + 2)) / 2);
my @matches;
while (<>) {
chomp;
next if not /^(.*?)($key)(.*)$/;
my ($lc, $rc) = ($1, $3);
my ($lstr, $llen) = get_last_n_hkchars($lc, $context_width);
my ($rstr, $rlen) = get_first_n_hkchars($rc, $context_width);
my $lfill = "_" x ($context_width - $llen);
my $rfill = "_" x ($context_width - $rlen);
my $ostr = "$lfill$lstr"."[".$key."]"."$rstr$rfill";
if ($sort_lr_context) {
if ($sort_lr_context =~ /^l/) {
push @matches, [join("", reverse split(//, $lstr)), $ostr];
} elsif ($sort_lr_context =~ /^r/) {
push @matches, [$rstr, $ostr];
}
} else {
print "$ostr\n";
}
}
if ($sort_lr_context) {
if ($reverse_mode) {
@matches = sort {$b->[0] cmp $a->[0]} @matches;
} else {
@matches = sort {$a->[0] cmp $b->[0]} @matches;
}
foreach my $l (@matches) {
print $l->[1]."\n";
}
}
# 先頭から半角N文字分取る
# 取った文字列と実際の長さ(半角文字数)を返す
sub get_first_n_hkchars {
my ($str, $n) = @_;
my $s = "";
my $slen = 0;
foreach my $c (split(//, $str)) {
my $clen = 2;
if (
$c =~ /\p{InBasicLatin}/
or
($c =~ /\p{InHalfwidthAndFullwidthForms}/ and $c =~ /\p{Katakana}/)
) {
$clen = 1;
}
last if $slen + $clen > $n;
$slen += $clen;
$s .= $c;
}
return ($s, $slen);
}
sub get_last_n_hkchars {
my ($s, $n) = @_;
my $sr = join("", reverse split(//, $s));
my ($str, $slen) = get_first_n_hkchars($sr, $n);
my $rv = join("", reverse split(//, $str));
return ($rv, $slen);
}