2010-02-15 51 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" ; 
} 
} 
相關問題