2015-08-29 40 views
0

我遇到了Perl脚本的问题,如下所示。无法打开由Perl中的readdir返回的文件

我必须打开并分析目录中的所有* .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"); 
#  
# } 
#} 

} 

+0

实际上,你使用正则表达式,但你提到的glob –

+0

我读过,用Perl可以有这样做的不止一种方式让事情更清晰。在这种情况下,您已经在@files中拥有文件名,也许您只需遍历该数组并使用正则表达式来过滤要查找的文件名即可。然后将文件名和目录名粘贴在一起,并使用该路径访问该文件。 – ewd

+0

'为我的$ fn(grep {$ _ =〜/\.txt$/} @files){'? – bytepusher

回答

-1

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

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

尽管'$ dir'可能是一个*引用*,但它通常被认为是一个词法目录句柄,最好这样想。 – Borodin

+0

该代码不会编译; “open”调用不会找到这些文件,因为它正在查看错误的目录,这是OP本来的问题;正则表达式不需要捕获'(。*)',它应该真的有一个与个案无关的修饰符'/ i' – Borodin

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 
} 
+0

感谢您的评论。我尝试过,但我有一个延续问题。以下代码有什么错误? – Agata

+0

请认真阅读代码:/第一条消息 – Agata

+0

我需要在指定时间内找到'programmi'目录下的所有程序。例如,如果所指示的时间是21,则必须返回在整个时间内提供的所有节目(因此,例如,那些编程为21:00,21:15,21:30,21:55等的节目) programmi'目录包含几个文本文件(例如,Rai 1,Rai 2,Rai 3,RaiMovie,Raisport1等),每个文件定义一天的电视节目时间表 – Agata