2013-09-27 26 views
2

我想遍歷每個文件夾中的文件,並從該文件獲取信息並將其更新到數組 例如。perl,使用File :: Find可以修改該函數之外的數據結構嗎?

use File::Find; 

sub main 
{ 
    my @names =(); 
    my $dir = "mydir";   

    # will traverse directories and look for file 'list.txt' 
    ### now, is it possible to update @names while traversing using find? 
    find(\&getNames(), $dir); 

} 

sub getNames 
{ 
    #I tried to take names as argument but it doesn't seem to work.. 
    if (-f $_ && $_ eq 'list.txt') 
    { 
     #update names possible? 
    } 
} 

是否有可能在使用File :: Find遍歷時更新數據結構? 而我試圖不使用全局變量..

回答

2

是的,它非常必須是可能的,使用一個漂亮的功能稱爲closures或匿名子例程。

試着改變你發現調用到這樣的事情:

find(sub { getNames(\@names, @_) }, $dir); 

在這裏,我定義一個封閉,在轉調用你的函數「getNames」,具有參考你的數據結構作爲第一參數後面跟隨查找本身提供的任何附加參數。

在getNames,您可以檢索的數據結構作爲第一個參數:

sub getNames 
{ 
    my @names = shift; 
    ... 

,只要你喜歡使用數組,沒有別的需要改變。

此外,在Perl閱讀關閉:http://perldoc.perl.org/perlfaq7.html#What%27s-a-closure%3F

+3

這應該是'$ names_ref'而不是'subname getNames'中的'@ names'。 –

+0

@SlavenRezic很好的接收! – Nikhil

0

您可能會發現它更容易使用的基於迭代器的文件中查找模塊像File::Next

#!/usr/bin/perl 

use warnings; 
use strict; 
use File::Next; 

my $iterator = File::Next::files('.'); 

while (my $file = $iterator->()) { 
    if ($file eq 'list.txt') { 
     print "Found list.txt\n"; 
    } 
} 

這樣做,這樣,你不必擔心你參與的功能範圍

您也可以讓文件::接下來做過濾你:

my $iterator = File::Next::files({ 
     file_filter => sub { $_ eq 'list.txt' }, 
    }, '.'); 

while (my $file = $iterator->()) { 
    # No need to check, because File::Next does the filtering 
    print "Found list.txt\n"; 
} 
+0

它是否也遍歷子目錄? –

+0

當然可以。如果沒有目錄遍歷,那麼你所需要的只是glob()函數。 http://search.cpan.org/dist/File-Next/ –

0

如果您不需要getNames其他地方,那麼你就可以在裏面main定義這個子程序作爲一個匿名的子程序。這個子程序中有@names

use File::Find; 

sub main 
{ 
    my @names =(); 
    my $dir = "mydir";   

    my $getNames = sub 
    { 
     if (-f $_ && $_ eq 'list.txt') 
     { 
      #update names possible? -> yes, @names is visible here 
     } 
    }; 

    # will traverse directories and look for file 'list.txt' 
    ### now, is it possible to update @names while traversing using find? 
    find($getNames, $dir); 

} 
相關問題