当最初检查ARGV [0]是否是文件或目录时,它可以正常工作并获得准确的结果。然后再进入子文件我再次尝试它并没有返回任何东西。这可能看起来像一个小傻问题,但我是学生,并在周末帮助编程很少。有时一双新的眼睛可以提供帮助。谢谢你。
#!/usr/bin/perl -w
my %hash;
my $args = @ARGV;
my $dh = $ARGV[0];
if ( -f $dh ) {
words($dh);
} elsif ( -d $dh ) {
files($dh);
}
sub words {
open( my $file, '<', $_[0] ) or die 'cant open file';
while ( my $line = <$file> ) {
chomp $line;
@words = split( /\s+/, $line );
foreach $word (@words) {
$word =~ tr/A-Z/a-z/;
$hash{$word}++;
}
}
foreach $key ( keys %hash ) {
print $key. " " . $hash{$key} . "\n";
}
}
sub files {
opendir( DH, $_[0] );
my @paths = grep !/^\./, readdir(DH);
closedir(DH);
foreach (@paths) {
if ( -f $_ ) {
print $_. "\n";
}
}
}
答案 0 :(得分:3)
您错过了文件的路径
if (-f "$_[0]/$_") ..
或使其不那么模糊,
sub files{
my ($path) = @_;
opendir(my $DH, $path);
my @paths = grep !/^\./, readdir($DH);
closedir($DH);
foreach (@paths) {
if (-f "$path/$_") {
print "$_\n";
}
}
}
答案 1 :(得分:1)
如前所述,readdir
的返回值仅包含基本名称。因此,要进行文件测试,您必须chdir
或明确包含路径信息。
if (-f "$_[0]/$_") {
一种替代解决方案是使用Path::Class
或类似的模块来执行跨平台路径规范操作。
以下是使用此模块重写的脚本:
use strict;
use warnings;
use Path::Class;
my $path = shift // die "Usage: $0 <Dir or File>\n";
words($path) if -f $path;
files($path) if -d $path;
sub words {
my $file = file(shift);
my %count;
$count{ lc($_) }++ for split ' ', $file->slurp;
for my $key ( keys %count ) {
printf "%s %s\n", $key, $count{$key};
}
}
sub files {
my $dir = dir(shift);
for ( $dir->children ) {
next if $_->is_dir;
print "$_\n", $_->basename;
}
}