【问题标题】:Perl iterating through each line in a file and appending to the end of each line in another filePerl 遍历文件中的每一行并附加到另一个文件中每一行的末尾
【发布时间】:2013-01-21 16:15:55
【问题描述】:

我有两个包含以下内容的文本文件:

FILE1.txt

dog
cat
antelope

FILE2.txt

1
2
Barry

我想要实现的输出如下:

dog1
dog2
dogBarry
cat1
cat2
catBarry
antelope1
antelope2
antelopeBarry

他们按照我的方式去做:

    open (FILE1, "<File1.txt") || die $!;
    open (FILE2, "<File2.txt") || die $!;

    my @animals = (<FILE1>);  #each line of the file into an array
    my @otherStrings = (<FILE2>);   #each line of the file into an array

    close FILE1 || die $!;
    close FILE2 || die $!;

    my @bothTogether;
    foreach my $animal (@animals) {
    chomp $animal;
            foreach my $otherString (@otherStrings) {
                    chomp $otherString;
                    push (@bothTogether,  "$animal$otherString");
            }
   }
   print @bothTogether; 

我的做法很有效,但我确信这不是最好的方法尤其是当文件都可能包含数千行时?

最好的方法是什么,也许使用哈希?

【问题讨论】:

  • 如果文件太大而无法存储,您只能在处理时读取它们(而不是之前,就像现在一样)。哈希无济于事,因为无论如何您都会将所有内容加载到内存中;并且您无论如何都在处理“foreach”。
  • 记一下,你也可以:my @animals = chomp(&lt;FILE1&gt;);
  • 另外我认为你的脚本在记忆方面是可以的,因为只有生成的文件会很大 - 你逐行编写它。

标签: perl file text hash


【解决方案1】:

您的方法适用于包含数千行的文件。那真的没那么大。对于数百万行,这可能是个问题。

但是,您可以通过仅将一个文件读入内存并立即打印结果而不是将它们存储在数组中来减少代码的内存使用量:

use warnings;
use strict;

open my $animals, '<', 'File1.txt' or die "Can't open animals: $!";
open my $payloads, '<', 'File2.txt' or die "Can't open payloads: $!";

my @payloads = <$payloads>;   #each line of the file into an array
close $payloads or die "Can't close payloads: $!";

while (my $line = <$animals>) {
    chomp $line;
    print $line.$_ foreach (@payloads);
}
close $animals or die "Can't close animals: $!";

如果有两个大小相同的大文件,这将使用大约 1/4 的原始代码内存。

更新:我还编辑了代码以包含 Simbabque 对其现代化的好建议。

更新 2: 正如其他人所指出的,您不能将这两个文件都读入内存,而是逐行遍历动物文件的每一行的有效负载文件。但是,这会慢得多。除非绝对必要,否则应避免。我建议的方法与您的原始代码的速度大致相同。

【讨论】:

  • 您也许可以使用您的代码帮助我解决与此相关的另一个问题,这是我个人资料中唯一未回答的问题,谢谢
【解决方案2】:

除了某些现代 Perl 方面(例如两个参数 open)之外,您的代码非常简单。

我能看到的唯一改进是您可以将内部 chomp 移动到一个额外的循环中,也许在您阅读文件时进行咀嚼。那会节省一些时间。但总而言之,如果您想对其他数据的每一行的数据做一些事情,那么您做对了。

由于优先级,您应该使用or die 而不是|| die,并且最终输出将是一长行,因为数组的项目中没有更多的换行符。

更新:@FrankB 在his above comment 中提出了一个很好的建议:如果您的文件很大并且您正在努力处理内存问题,您不应该将它们吞入并放在两个数组中,而是逐行读取和处理第一行,然后为第一行中的每一行打开并读取第二行。这需要更长的时间,但可以节省大量内存。然后,您也可以直接输出结果,而不是将它们推送到结果数组中。

【讨论】:

  • 感谢顶一下或者||优先,意识到我的错误。您也许还可以帮助解决我的另一个问题,这是我个人资料中唯一未回答的问题,谢谢
猜你喜欢
  • 1970-01-01
  • 2018-06-15
  • 2016-04-04
  • 2010-09-23
  • 2014-11-13
  • 1970-01-01
  • 2020-02-02
  • 2013-06-24
  • 2012-12-08
相关资源
最近更新 更多