【问题标题】:How to prepend auto incrementing number to array?如何将自动递增的数字添加到数组中?
【发布时间】:2011-11-12 06:47:05
【问题描述】:

我正在通过以下代码在 perl 中读取文件内容

my @files = glob("$PATH/*");
foreach my $file (@files){
    open(MYFILE,"<$file");
    my @fileContent = <MYFILE>;
    close(MYFILE);
}

现在,我想在每一行添加自动递增的数字。像--

fileContent[0] = 1: This
fileContent[1] = 2: is
fileContent[2] = 3: a
fileContent[3] = 4: text
fileContent[4] = 5: file.

有人知道一种有效的方法吗?

谢谢!

【问题讨论】:

    标签: arrays perl file


    【解决方案1】:

    单线怎么样?

    perl -wne 'print "$.: $_"; close ARGV if eof;' path/*
    

    或者在脚本中,带有一个数组:

    use strict;
    use warnings;
    use autodie;
    
    while (<tmp/data*>) {
        open my $fh, '<', $_;
        my @fileContent;
        push @fileContent, "$.: $_" while <$fh>;
    }
    

    $.here. 上的文档

    【讨论】:

    • 如果您需要格式化数字(例如,特定宽度),您也可以使用sprintf,我建议您查看perlvar 以获取有关$. 的更多信息。
    • 感谢您的回答!剧本最适合我! :)
    【解决方案2】:

    在你的作业线上试试这个:

    my $i;
    my @fileContent = map{++$i.":  $_"} (<MYFILE>)
    

    【讨论】:

    • 这在大文件上可能有点慢,但可以很容易地转换成for 循环来解决这个问题。
    • 嘿!看起来不错,但你说的文件有多大?
    • 在计算机方面很大。很大,需要很长时间才能从磁盘加载所有内容或无法读取到内存中。
    【解决方案3】:

    高效?我不知道真的有一种低效的方法可以做到这一点(除非你故意让它低效)。

    for my $lineNumber (1..@fileContent) {
        substr( $fileContent[$lineNumber-1], 0, 0, "$lineNumber: " );
    }
    

    【讨论】:

    • 感谢您的建议,但我认为循环是一种低效的方法,因为它对多个文件执行此操作,并且每个文件都有成百上千行。
    • for 循环可能是最快的方法。而且,它也非常快。处理数百个文件并且每个文件都有数百或数千行不会超过一分钟。您可以使用 Perl map 函数。它更短,因为它只需要一行代码,它也更酷,因为当我们使用它时,女孩们会晕倒“哦,他好热!他知道如何使用 Perl 的“map”命令。但是, map 的执行速度可能比 for 循环慢。
    • @David 所有酷女孩都这样说。我们都知道。但是,在内存使用方面,while 可能更可取。
    • @TLP:关于 while 命令占用更少内存的说法是正确的。
    • 读取文件的开销将使任何其他时间效率变得微不足道。如果您在谈论内存效率,从您的原始示例中我假设您需要将整个文件加载到内存中。如果没有,那比添加行号的方式更能提高效率
    【解决方案4】:

    这是您的代码,已编辑为使用词法变量、打开 3 个 arg 和添加行号的 map 语句。

    my @files = glob("$PATH/*");
    foreach my $file (@files){
        open my $fh,'<', $file or die $!;
        my $i = 1;
        my @fileContent = map {$i++.": $_"} <$fh>;
    
        # do something with @fileContent
    }
    

    这里有一个更糟糕的例子(使用更多的自动功能):

    for (<$PATH/*>) {
        local @ARGV = $_;
        my $i = 1;
        my @lines = map {$i++.": $_"} <>;
    
        # do something with @lines
    }
    

    这是一个使用$.(输入行号)和while循环逐行读取文件的示例。

    for (<$PATH/*>) {
        local (@ARGV, $_) = $_;
        my @lines;
        push @lines, "$.: $_" while <>;
    
        # do something with @lines
    }
    

    【讨论】:

    • 我做了一个快速测试,至少用 perl 5.12 重置了数字
    【解决方案5】:

    将您的开放更改为:

    open MYFILE, '-|', 'grep', '-n', '', $file
    

    【讨论】:

      猜你喜欢
      • 2022-07-05
      • 2021-03-10
      • 1970-01-01
      • 2020-10-15
      • 2021-03-03
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      • 2019-02-22
      相关资源
      最近更新 更多