2

我正在尝试遍历每个文件夹中的文件并从该文件中获取信息并将其更新为数组 For ex。

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 遍历时是否可以更新数据结构?而且我试图不使用全局变量..

4

3 回答 3

2

是的,它非常有可能,使用称为闭包或匿名子例程的漂亮特性。

尝试将您的 find 调用更改为以下内容:

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

在这里,我定义了一个闭包,它依次调用您的函数“getNames”,将您的数据结构的引用作为第一个参数,然后是 find 本身提供的任何其他参数。

在 getNames 中,您可以检索数据结构作为第一个参数:

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

随心所欲地使用数组,无需更改任何其他内容。

另外,阅读 Perl 中的闭包:http: //perldoc.perl.org/perlfaq7.html#What%27s-a-closure%3F

于 2013-09-27T19:19:16.727 回答
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";
    }
}

这样做,您不必担心您所在功能的范围。

你也可以让 File::Next 为你做过滤:

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";
}
于 2013-09-27T19:42:56.160 回答
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);

}
于 2013-09-27T20:08:36.263 回答