当前位置: 首页 > 知识库问答 >
问题:

用Perl查找文件

曾典
2023-03-14

这个问题比原来的标题(“原型和子例程的正向声明”!)简单得多让我们开始吧。我希望答案,无论多么简单,都能帮助我理解子程序/函数、原型和范围以及文件::Find模块。

在Perl中,子例程几乎可以出现在任何地方,通常不需要进行前向声明(除非子例程声明了一个原型,我不知道如何在Perl中以“标准”的方式执行)。对于我通常使用Perl所做的事情,这些不同的运行somefunction的方法几乎没有区别:

sub somefunction;  # Forward declares the function
&somefunction; 
somefunction();
somefunction;   # Bare word warning under `strict subs`

我经常使用find2perl生成代码,并将其抄录/破解成脚本的一部分。这很可能是一种糟糕的风格,现在我的脏衣服已经公开了,但也可以这样:-)对于File::Find来说,wanted函数是一个必需的子例程-find2perl创建它并添加sub wanted 到它创建的结果脚本。有时候,当我编辑脚本时,我会从sub-wanted中删除“sub”,最后它会变成

Use of uninitialized value $_ in lstat at findscript.pl line 29

我的问题是:为什么会发生这种情况,这是一个真正的问题吗?这“只是一个警告”,但我想更好地理解它。

  • 文档和代码显示,$\uuu是在子通缉{}中本地化的。如果我使用wanted(),为什么它是未定义而不是所需的sub

我的猜测是,转发声明表单以某种方式“初始化”所需的,以便第一次使用时不会有空的默认变量。我想这就是原型——即使是Perl原型,比如它们存在的原型——的工作原理。我尝试浏览Perl源代码,以了解当使用sub function而不是function()调用函数时,sub在做什么,但这可能是我目前无法理解的。

任何加深(和加快)我对此的理解的帮助都是非常感激的。

编辑:这是Stack上最近的一个示例脚本

编辑:正如我在下面的评论中指出的(但我也会在这里标记它):几个月来,我一直在使用路径::迭代器::规则而不是File::Find。它需要perl


共有3个答案

齐望
2023-03-14

我建议使用File::Find::wanted中的Find_wanted函数,而不是File::Find::wanted

find_wanted需要两个参数

  • 对于您想要的任何文件名,返回true的子例程
  • 您正在搜索的文件列表

find_want返回一个数组,其中包含找到的文件名列表。


我使用如下代码查找计算机上特定目录中的所有JPEG文件:

my @files = find_wanted( sub { -f && /\.jpg$/i }, @dirs );

为可能需要的人解释一些语法:

sub{…}是一个匿名子例程,其中 替换为子例程的代码
-f检查文件名是否指向“普通文件”

晏富
2023-03-14

子目录中删除子目录只是调用想要的函数,而不是转发声明。

然而,想要的函数并不是直接从代码中调用的,而是由File::Find调用的。File::Find在调用它之前会做一些有用的事情,比如填充$\ucode>。

这里不需要转发声明想要的,但是如果想要删除转发声明,请删除整个子想要的 行-不仅仅是单词sub

宰父深
2023-03-14

我不太喜欢菲尔e::F。只是工作不正常。代码查找命令不返回文件列表,因此您必须在代码查找中使用非本地数组变量来捕获您找到的文件列表(不好),或者将您的整个程序放置在您想要的子例程(甚至更糟)。另外,单独的子程序意味着您的逻辑与查找命令是分开的。它只是丑陋。

我所做的是在我的find命令中内联我的wanted子例程。子例程与find保持一致。另外,我的非局部数组变量现在只是我的find命令的一部分,看起来不那么糟糕

下面是我如何处理文件::Find——假设我想要的文件具有。pl后缀:

my @file_list;
find ( sub {
    return unless -f;       #Must be a file
    return unless /\.pl$/;  #Must end with `.pl` suffix
    push @file_list, $File::Find::name;
}, $directory );

# At this point, @file_list contains all of the files I found.

这与:

my @file_list;

find ( \&wanted, $directory );

sub wanted {
    return unless -f;
    return unless /\.pl$/;
    push @file_list, $File::Find::name;
}

# At this point, @file_list contains all of the files I found.

在衬里只是看起来更好。它把我的代码放在一起。另外,我的非局部数组变量看起来也不那么奇怪。

我也喜欢以这种特殊的方式利用较短的语法。通常情况下,我不喜欢使用推断的$\ucode>,但在这种情况下,它使代码更易于阅读。我最初的通缉令与此相同:

sub wanted {
    my $file_name = $_;
    if ( -f $file_name and $file_name =~ /\.pl$/ ) {
        push @file_list, $File::Find::name;
    }
}

File::Find使用起来并不难。你只需要记住:

  • 当您找到不需要的文件时,可以使用return转到下一个文件

而且,最简单的方法是将想要的文件推送到一个数组中,然后在以后的程序中使用该数组。

 类似资料:
  • 你会认为这是一件简单的事情。我有一个在我的集合中的对象ID列表。我想根据对象ID获得一条记录。谷歌过,但没有任何帮助。 所以我有对象id:5106c7703abc120a04070b34 此打印: 我试过上述发现的不同版本。它们都无法编译: 查找({_id= 它们都不起作用。如何使用对象id查找(findone)单个记录??

  • 错误:NoSuChelementException:没有这样的元素:无法定位元素:{“method”:“xpath”,“selector”:“//td[@class='c($PrimaryColor)W(51%)']”}(会话信息:chrome=77.0.3865.120) 我的代码如下: 这是我试图从“https://finance.yahoo.com/quote/goog?p=goog”中搜索

  • 主要内容:open 函数,实例,Sysopen函数,Close 函数,读写文件,实例,实例,read 函数,实例,实例,指定文件位置,文件信息,实例Perl 使用一种叫做文件句柄类型的变量来操作文件。 从文件读取或者写入数据需要使用文件句柄。 文件句柄(file handle)是一个 I/O 连接的名称。 Perl 提供了三种文件句柄: STDIN,STDOUT,STDERR, 分别代表标准输入、标准输出和标准出错输出。 Perl 中打开文件可以使用以下方式: 参数说明: FILEHANDLE:

  • Perl 使用一种叫做文件句柄类型的变量来操作文件。 从文件读取或者写入数据需要使用文件句柄。 文件句柄(file handle)是一个I/O连接的名称。 Perl提供了三种文件句柄:STDIN,STDOUT,STDERR,分别代表标准输入、标准输出和标准出错输出。 Perl 中打开文件可以使用以下方式: open FILEHANDLE, EXPR open FILEHANDLE sysope

  • 问题内容: 除了以下以外,任何人都有另一种在bash中查找和复制文件的方式: 我喜欢这种方式,因为它很灵活,因为我正在构建命令(可以通过任何命令执行)并在之后执行它。 还有其他简化命令到文件列表的方法吗? 谢谢 问题答案: 我建议使用的选项: 与往常一样,请查阅手册页以获得最佳结果。

  • 主要内容:实例,实例,实例,什么是 POD?,实例Perl 中可以在模块或脚本中嵌入 POD(Plain Old Documentation) 文档。 POD 是一种简单而易用的标记型语言(置标语言)。 POD 文档使用规则: POD 文档以 =head1 开始, =cut 结束, =head1 前与 =cut 后添加一空行。 Perl 会忽略 POD 中的文档。实例如下: 实例 #!/usr/bin/perl print "Hello, Wor