I'm just getting back to Perl after being away for a while
and am now using it on Windows instead of Unix as before.
I've written a Perl script that works like Unix "wc",
because I missed it on Windows, and to brush up my Perl
after the absence. This works fine as long as I enter
file names/globs on the command line, but I'd like it to
be able to read from a pipe, too, as Unix wc does, e.g.,
cat somefilename | wc
Well, on Windows I guess that would be "type somefilename".
I'm including the full code below, but I think the
relevant parts are:
@filenames = @ARGV ? map {glob($_)} @ARGV : STDIN;
and
if (!$FH->open($_)) {
warn qq(Couldn't open "$_" for input\n);
next;
}
If I just use STDIN or *STDIN, I get
"Couldn't open *main::STDIN for input".
If I use \*STDIN, I get
"Couldn't open GLOB(hex) for input".
What am I doing wrong here? Any help much appreciated.
Thanks.
P.S. Of much less importance, I tried to use Getopt::Long
for option handling and it wouldn't allow option
bundling, even though I said Getopt::Long::Configure("bundling"
. (Seems to me it used to allow bundling of
single char options by default.) Anybody had any experience
with this?
and am now using it on Windows instead of Unix as before.
I've written a Perl script that works like Unix "wc",
because I missed it on Windows, and to brush up my Perl
after the absence. This works fine as long as I enter
file names/globs on the command line, but I'd like it to
be able to read from a pipe, too, as Unix wc does, e.g.,
cat somefilename | wc
Well, on Windows I guess that would be "type somefilename".
I'm including the full code below, but I think the
relevant parts are:
@filenames = @ARGV ? map {glob($_)} @ARGV : STDIN;
and
if (!$FH->open($_)) {
warn qq(Couldn't open "$_" for input\n);
next;
}
If I just use STDIN or *STDIN, I get
"Couldn't open *main::STDIN for input".
If I use \*STDIN, I get
"Couldn't open GLOB(hex) for input".
What am I doing wrong here? Any help much appreciated.
Thanks.
P.S. Of much less importance, I tried to use Getopt::Long
for option handling and it wouldn't allow option
bundling, even though I said Getopt::Long::Configure("bundling"

single char options by default.) Anybody had any experience
with this?
Code:
#!/bin/perl
##########################################################################
#usage: $routine -[lcwdh] [file(s)]
#Prints count of lines, words, characters in files, like *nix "wc"
#Options:
# -l count lines in file(s)
# -w count words in file(s)
# -c count characters in file(s)
# (Note: if none of l,w, or c are specified, does all 3!)
#
# -h print this help and exit
# -d print debugging output
##########################################################################
use strict;
(my $routine = $0) =~ s#^.*(\\|\/)##; #routine name, minus path
my $debug;
my @filenames;
my $line;
my $line_count;
my $word_count;
my $char_count;
my $line_total = 0;
my $word_total = 0;
my $char_total = 0;
my $line_print;
my $word_print;
my $char_print;
my %opt;
my $show_all;
my $FH;
&process_options;
@filenames = @ARGV ? map {glob($_)} @ARGV : STDIN;
&usage unless @filenames;
&print_heading;
&process_files;
&print_totals if (@filenames > 1);
exit(0);
################################## SUBROUTINES ##############################################
sub process_files {
use FileHandle;
$FH = FileHandle->new;
for (@filenames) {
#if (! -T $_) {
# warn qq("$_" doesn't exist or isn't a text file\n);
# next;
#}
if (!$FH->open($_)) {
warn qq(Couldn't open "$_" for input\n);
next;
}
$line_count = 0;
$word_count = 0;
$char_count = 0;
while (not($FH->eof)) {
$line = $FH->getline;
$line_count++;
$word_count += split(/\s+/, $line);
}
$char_count = $FH->tell;
&print_detail;
$line_total += $line_count;
$word_total += $word_count;
$char_total += $char_count;
$FH->close || die qq(Couldn't close "$_\n");
}
} #end process_files
sub print_heading {
printf "%9s ", "lines" if $line_print;
printf "%9s ", "words" if $word_print;
printf "%9s ", "chars" if $char_print;
printf "%-s\n", "file";
} #end print_heading
sub print_detail {
printf "%9d ", $line_count if $line_print;
printf "%9d ", $word_count if $word_print;
printf "%9d ", $char_count if $char_print;
printf "%-s\n", $_;
} #end print_detail
sub print_totals {
printf "%9d ", $line_total if $line_print;
printf "%9d ", $word_total if $word_print;
printf "%9d ", $char_total if $char_print;
printf "%-s\n", "total";
} #end print_totals
sub usage {
warn <<ENDUSAGE;
usage: $routine -[lcwdh] [file(s)]
Prints count of lines, words, characters in files, like *nix "wc"
Options:
-l count lines in file(s)
-w count words in file(s)
-c count characters in file(s)
(Note: if none of l,w, or c are specified, does all 3!)
-h print this help and exit
-d print debugging output
ENDUSAGE
exit(1);
} #end usage
sub process_options {
use Getopt::Std; #can't get Getopt::Long to work with bundling!
getopts(q(lwcdh), \%opt) || &usage;
$debug = $opt{d};
if (!defined($opt{l}) && !defined($opt{w}) && !defined($opt{c})) {
#if we entered none of the above options, it's the same as entering them all!
$show_all = 1;
}
($line_print, $word_print, $char_print) = map {$_ || $show_all} @opt{qw(l w c)};
&usage if $opt{h};
} #end process_options
__END__