perl - 我应该手动设置 Perl 的 @ARGV 以便我可以使用 <> 打开、扫描和关闭文件吗?

标签 perl file input

我最近开始学习 Perl,我最近的一项任务是在一堆文件中搜索特定字符串。用户提供目录名称作为参数,程序在该目录中的所有文件中搜索模式。使用 readdir()我已经设法构建了一个包含所有可搜索文件名的数组,现在需要搜索每个文件的模式,我的实现看起来像这样 -

sub searchDir($) {
    my $dirN = shift;
    my @dirList = glob("$dirN/*");
    for(@dirList) {
        push @fileList, $_ if -f $_;

    }
    @ARGV = @fileList;
    while(<>) {
        ## Search for pattern
    }
}

我的问题是 - 是否可以像上面所做的那样手动加载 @ARGV 数组并使用 <> 运算符扫描单行,还是应该单独打开/扫描/关闭每个文件?如果这个处理存在于子程序中而不是在主函数中,会有什么不同吗?

最佳答案

关于操纵@ARGV 的话题——这绝对是有效的代码,Perl 肯定允许你这样做。我不认为这是一个好的编码习惯。我见过的大多数使用“while (<>)”习语的代码都是用它来读取标准输入,这就是我最初希望您的代码执行的操作。更易读的模式可能是单独打开/关闭每个输入文件:

foreach my $file (@files) {
    open FILE, "<$file" or die "Error opening file $file ($!)";
    my @lines = <FILE>;
    close FILE or die $!;

    foreach my $line (@file) {
        if ( $line =~ /$pattern/ ) {
            # do something here!
        }
    }
}

这对我来说更容易阅读,尽管它是多几行代码。 Perl 为您提供了很大的灵活性,但我认为这使得在 Perl 中开发您自己的风格变得更加重要,该风格对您(和您的同事,如果这对您的代码/职业很重要)是可读和可理解的。

将子例程放在主函数或子例程中也是一种风格决定,您应该尝试和考虑。现代计算机在这方面的速度如此之快,以至于样式和可读性对于此类脚本来说更为重要,因为您不太可能遇到此类脚本使您的硬件负担过重的情况。

祝你好运! Perl 很有趣。 :)

编辑:当然,如果他有一个非常大的文件,他应该做一些比将整个文件放入数组更聪明的事情。在那种情况下,这样的事情肯定会更好:
while ( my $line = <FILE> ) {
    if ( $line =~ /$pattern/ ) {
        # do something here!
    }
}

我写“您不太可能遇到这样的脚本使您的硬件负担过重的情况”的意思是为了涵盖这一点,抱歉没有更具体。再说了,谁有4GB的硬盘,更别说4GB的文件了? :P

另一个编辑:根据评论者的建议仔细阅读 Internet 后,我​​意识到可以购买比 4GB 大得多的硬盘驱动器。我感谢评论者指出这一点,并 promise 将来永远不会尝试在互联网上发表讽刺评论。

关于perl - 我应该手动设置 Perl 的 @ARGV 以便我可以使用 <> 打开、扫描和关闭文件吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/506009/

相关文章:

php - 将输入传递给 C 程序并使用 php 获取输出

angular - 尽管在 Angular 中重置了表单,但输入字段仍被标记为红色

python - 将输入的以空格分隔的项目添加到字典中。 Python

mysql - 尝试通过使用多个表作为过滤器,在 Perl 中使用 sqlite 从数据库中提取数据

java - 用 Java 写入 Perl 进程输入流

javascript - 加载脚本: innerHTML vs.appendChild

python - 打开从 os.listdir() 找到的文件并对文件执行任务

regex - perl 正则表达式搜索问题并用环境变量替换

java - 将数据结构从 java 传递到 perl(反之亦然)

c++ - 使用二进制确定图像文件的扩展类型