2010-02-15 50 views
5

在Perl中,你可以得到与模式匹配的文件列表:如何在Perl中将变量的值用作glob模式?

my @list = <*.txt>; 
print "@list"; 

现在,我想传递的图案作为一个变量(因为它传递给函数)。但是这不起作用:

sub ProcessFiles { 
    my ($pattern) = @_; 
    my @list = <$pattern>; 
    print "@list"; 
} 

readline() on unopened filehandle at ... 

有什么建议吗?

回答

12

使用glob

use strict; 
use warnings; 

ProcessFiles('*.txt'); 

sub ProcessFiles { 
    my ($pattern) = @_; 
    my @list = glob $pattern; 
    print "@list"; 
} 

这里是为什么你得到警告,从I/O Operators的解释:

如果什么尖括号包含是 一个简单的标量变量(例如, $ foo),那么该变量将包含 文件句柄的名称,从而输入 .. 。它被认为是清洁剂直接调用内部函数的水珠($ foo的),这可能是摆在首位,以做它正确的方式。)

-1

怎样用“eval”命令来包装它?像这样...

sub ProcessFiles { 
    my ($pattern) = @_; 
    my @list; 
    eval "\@list = <$pattern>"; 
    print @list; 
} 
+1

永远,永远,永远,永远做到这一点。 “glob”运算符是正确的答案。 – friedo 2010-02-15 03:57:07

+0

你说得对,glob是一个更好的答案。感谢您的更正。为什么“永远,永远,永远”这样做? – 2010-02-16 00:57:49

+1

罗伯特,你应该尽可能避免使用字符串'eval';谁知道恶意数据可能以'$ pattern'结尾,特别是如果这是从用户输入派生的。即使不是恶意的,奇怪的东西进入“eval”可能会导致许多痛苦的错误。 – friedo 2010-02-19 17:13:23

0

为什么不传文件功能列表的数组引用?

my @list = <*.txt>; 
ProcessFiles(\@list); 

sub ProcessFiles { 
    my $list_ref = shift; 
    for my $file (@{$list_ref}) { 
     print "$file\n"; 
    } 
} 
+1

我知道有人会提出这个建议。问题是它实际上是一个变量,如下所示:'my $ pattern =“test-%d - *。txt”; ProcessFiles(sprintf($ pattern,“51”));' – Frank 2010-02-15 03:56:25

0
use File::Basename; 
@ext=(".jpg",".png",".others"); 
while(<*>){ 
my(undef, undef, $ftype) = fileparse($_, qr/\.[^.]*/); 
if (grep {$_ eq $ftype} @ext) { 
    print "Element '$ftype' found! : $_\n" ; 
} 
} 
相关问题