Perl迭代遍历文件中的每一行,并将其附加到另一个文件中的每一行末尾。

4

我有两个文本文件,分别包含以下内容:

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; 

我现在用的方法是有效的,但我相信这不是最好的方法,特别是当文件可能包含数千行时?

那么做这件事的最佳方法是什么,也许使用哈希表?


1
如果文件太大无法放入内存,您只能在处理期间读取它们(而不是像现在这样在之前读取)。哈希表也没有帮助,因为您无论如何都要将所有内容加载到内存中; 而且您正在使用“foreach”进行处理。 - FrankB
只是一条注释,你也可以这样写:my @animals = chomp(<FILE1>); - Alexander Farber
我认为你的脚本在内存方面应该没问题,因为只有最终生成的文件会很大 - 而且你是逐行写入的。 - Alexander Farber
2个回答

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: 正如其他人所指出的,你可以不将任何一个文件读入内存,在动物文件的每一行中遍历载荷文件的每一行。然而,这样做速度会慢很多。除非绝对必要,否则应该避免使用这种方法。我提供的方法与你的原始代码速度大致相同。


你也许可以用你的代码帮我解决另一个与此相关的问题,这是我个人资料中唯一未回答的问题,谢谢。 - yonetpkbji

1
除了某些现代 Perl 方面(例如两个参数的 open),您的代码非常直观。
我唯一能看到的改进是,您可以将内部的 chomp 移入一个额外的循环中,也许在读取文件时进行修剪。这将节省一些时间。但总的来说,如果您想对其他数据的每一行数据执行某些操作,那么您做得很好。
由于优先级问题,您应该使用 or die 而不是 || die,而且最终输出将成为一行长字符串,因为数组项中没有更多换行符。

更新:@FrankB在他上面的评论中提出了一个好建议:如果你的文件很大,而且你在处理内存方面有困难,你不应该将它们读入并放入两个数组中,而是逐行读取和处理第一个数组,并为这些第一个数组的行打开和读取第二个数组。这需要更长的时间,但可以节省大量内存。然后你也直接输出结果,而不是将它们推入你的结果数组中。


谢谢你提供关于或||优先级的建议,我意识到了我的错误。你可能还能帮忙回答我的另一个问题,这是我档案中唯一未解决的问题,谢谢。 - yonetpkbji

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接