Perl遍历文件中的每一行并附加到另一个文件中每行的末尾

时间:2013-02-06 12:49:49

标签: perl file text hash

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

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; 

我这样做的方式有效,但我确定这不是解决问题的最佳方法,特别是当文件包含数千行时?

这样做的最佳方式是什么,可能使用哈希?

2 个答案:

答案 0 :(得分:5)

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

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

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:正如其他人所说,你可以将这两个文件都读入内存,在动物文件的每一行逐行浏览有效载荷文件。但是,这会慢得多。除非绝对必要,否则应该避免。我建议的方法与原始代码的速度大致相同。

答案 1 :(得分:1)

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

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

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

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