无法打开Perl中的readdir返回的文件

时间:2015-08-29 17:11:11

标签: perl

我的Perl脚本有问题,如下所示。

我必须打开并分析目录中的所有* .txt文件,但我不能。

我可以读取保存在@files数组中并打印的文件名,但我无法打开这些文件进行阅读。

这是我的代码: my $dir= "../Scrivania/programmi" ;

opendir my ($dh), $dir;
my @files = grep { -f and /\.txt/i } readdir $dir;
closedir $dh;

for my $file ( @files ) {
$file = catfile($dir, $file);
print qq{Opening "$file"\n};
open my $fh, '<', $file;

# Do stuff with the data from $fh

print "sono nel foreach\n";
print " in : "."$fh\n";
#open(CANALI,$fh);
#@righe=<CANALI>;
#close(CANALI);
#print "canali:"."@righe\n";
#foreach $canali (@righe)
#{
#   $canali =~ /\d\d:\d\d (-) (.*)/;
#   $ora= $1;
#   
#   if($hhSplit[0] == $ora) 
#   {
#       push(@output, "$canali");
#       
#   }
#}

}

2 个答案:

答案 0 :(得分:1)

您遇到的主要问题是readdir返回的文件名没有路径,所以当您应该打开x.txt时,您会尝试打开../Sc/direct/x.txt }。该文件不存在于当前工作目录中,因此open调用失败

glob("$dir/(.*).txt/")中你也有一些奇怪的混合物看起来有点像正则表达式模式,而glob并不理解。 $dir的值是从第一行opendir左侧打开的目录句柄。你应该使用的是glob '../Sc/direct/*.txt',但是不需要readdir

有两种方法可以找到文件的内容。您可以使用opendirreaddir来阅读目录中的所有内容,也可以使用glob

第一种方法只返回每个条目的裸名称,这意味着您必须将每个名称与包含目录的路径连接起来,最好使用File::Spec::Functions中的catfile。它还包括伪目录...,因此您必须先过滤掉这些目录,然后才能使用名称列表

glob没有这些缺点。它返回的所有字符串都是真实的目录条目,如果您在作为参数传递的模式中提供了一个路径,它们将包含一个路径

你似乎已经变得相当混乱,所以我写了这个程序,区分这两种方法。我希望它能让事情更清楚

use strict;
use warnings;
use v5.10.1;
use autodie;

use File::Spec::Functions qw/ catfile /;

my  $dir = '../Sc/direct';


### Using glob

for my $file ( glob catfile($dir, '*.txt') ) {
    print qq{Opening "$file"\n};
    open my $fh, '<', $file;

    # Do stuff with the data from $fh
}


### Using opendir / readdir

opendir my ($dh), $dir;
my @files = grep { -f and /\.txt$/i } readdir $dir;
closedir $dh;

for my $file ( @files ) {
    $file = catfile($dir, $file);
    print qq{Opening "$file"\n};
    open my $fh, '<', $file;

    # Do stuff with the data from $fh
}

答案 1 :(得分:-1)

在glob中使用$dir是不正确的。 $dir是GLOB类型而不是字符串值。相反,您应该循环遍历@files数组并查找与您想要的名称相匹配的名称。也许是这样的:

foreach my $fp (@files) {
  if ($fp =~ /(.*).txt/) {
    print "$fp is a .txt\n";
    open (my $in, "<", $fp)
    while (<$in>) ...
  }
}