Skip to content

Instantly share code, notes, and snippets.

@sago35
Created December 1, 2016 14:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sago35/76e26a4e3603dbc1438bbe2471e571df to your computer and use it in GitHub Desktop.
Save sago35/76e26a4e3603dbc1438bbe2471e571df to your computer and use it in GitHub Desktop.
wc.pl : Sample code of Getopt::Kingpin
use strict;
use warnings;
use Getopt::Kingpin;
my $kingpin = Getopt::Kingpin->new($0, 'print the number of newlines, words, and bytes in files');
my $flag = {
lines => $kingpin->flag('lines', 'print the newline counts')->short('l')->bool,
words => $kingpin->flag('words', 'print the word counts')->short('w')->bool,
chars => $kingpin->flag('chars', 'print the character counts')->short('m')->bool,
bytes => $kingpin->flag('bytes', 'print the byte counts')->short('c')->bool,
max_line_length => $kingpin->flag('max-line-length', 'print the length of the longest line')->short('L')->bool,
};
my $files = $kingpin->arg('file', 'target file[s]')->required->existing_file_list;
$kingpin->version('0.02');
$kingpin->parse;
my @results;
my $total = {filename => 'total'};
my @files = @{$files->value};
foreach my $file (@files) {
my %info = (
lines => (scalar $file->lines),
words => (scalar split /\s+/, $file->slurp_raw),
chars => (scalar split //, $file->slurp_raw),
bytes => (length $file->slurp_raw),
max_line_length => (calc_max_line_len($file->lines)),
);
push @results, {
filename => $file->canonpath,
%info,
};
foreach my $key (keys %info) {
$total->{$key} += $info{$key};
}
}
my @keys;
foreach my $k (qw(lines words chars bytes max_line_length)) {
if ($flag->{$k}) {
push @keys, $k;
}
}
# オプションがない場合は、-wlm とする
if ((scalar @keys) == 0) {
push @keys, qw(words lines chars);
}
# 結果出力
foreach my $result (@results) {
print_result($result);
}
if ((scalar @results) > 1) {
# 複数ファイル存在するならtotalを出力する
print_result($total);
}
sub print_result {
my ($r) = @_;
printf "%s\n",
join " ",
(map {sprintf "%9d", $r->{$_}} @keys),
$r->{filename};
}
sub calc_max_line_len {
my @lines = @_;
my $max = 0;
foreach my $line (@lines) {
chomp $line;
if ($max < length $line) {
$max = length $line;
}
}
return $max;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment