perl脚本在公共字段上连接两个文件

时间:2014-04-30 16:01:06

标签: perl

我正在编写一个perl脚本,根据2个原始文件中的公共字段值将两个不同文件中的字段连接到第三个新文件中。

我编写了以下脚本,但它似乎进入了一个无限循环。关于我需要改变什么的任何建议?

#!/usr/bin/perl
#
open FILE, ">location.txt" or die$!;
open FILE1, "./checkins.txt" or die$!;
open FILE2, "./locations.txt" or die$!;

while (my $line1 = <FILE1> and my $line2 = <FILE2>) {
    chomp $line1;
    chomp $line2;
    @lines1 = split("\t", $line1);
    @lines2 = split("\t", $line2);

    while($lines2[0] = $lines1[5]) {
        print FILE
            "$lines2[0]"."\t"."$lines2[1]"."\t"."$lines2[2]"."\t"."$lines1[6]"."\t".
            "$lines1[7]"."\t"."$lines1[8]"."\n";
    }
}
close(FILE);
close(FILE1);
close(FILE2);

2 个答案:

答案 0 :(得分:4)

20世纪90年代,并希望他们的Perl语法回来......

很抱歉。这不是你的错。

自早期以来,Perl语法已经发生了很大的变化,并且出于某种原因,大多数人仍然使用较旧的语法形式。它在学校教授,人们从工作场所的例子中汲取教训。 Python开发人员将不可读的 Perl语法解密为Perl是一种旧的破旧语言,现在属于历史的垃圾箱。但是,在很多方面,糟糕的Perl语法证明了获取Perl并学习它是多么容易。

始终将use strict;use warnings;放在程序的顶部。这将捕获Perl中大约90%的错误。如果您在=语句中使用eq而非==while,则会发现错误。获取Learning Perl(又名_The Llama Book)的新副本。仔细检查并获取新语法。这将大大提高您的编码技能。

另一个问题是你的内部while循环是一个无限循环。你并没有真正改变任何东西的价值,所以你不断地反复循环。以下是同样的事情:

while ( $foo ne $bar ) {
    print "Are we there yet?\n";
}

如果$foo不等于$bar,则上述循环将继续打印Are we there yet?数十亿年,直到太阳耗尽其最后一点氦燃料,并且扩展成一颗吞噬地球轨道的巨大恒星(或直到你厌倦了它并击中Control-C)。

如果您不想要无限循环,则必须更改while语句中使用的至少一个值:

while ( $foo ne $bar ) {
    print "Are we there yet?\n";
    $foo = $bar;    # One more peep, and I'll stop the car!
}

另外,如果一个文件包含的行多于另一个文件,会发生什么?我有一种感觉,你想做的是将一个文件读入一个哈希,然后循环浏览另一个文件。如果第二个文件中存在该哈希键,则需要组合这些行。不幸的是,您的问题并不清楚您想要做什么。

您可以编辑您的问题,以便更好地解释您尝试完成的内容。例如,如果您可以为我们提供两个输入文件的示例输入以及您希望输出文件的样子。你只需要给我们几行,但这将有助于我们更好地理解你想做什么。

答案 1 :(得分:3)

您使用的是作业=而非等级考试eq,而且应该是if而不是while

while($lines2[0] = $lines1[5]) {

将其更改为:

if ($lines2[0] eq $lines1[5]) {

顺便说一句,总是在每个脚本的顶部包含use strict;use warnings;。如果你正在进行文件处理,use autodie;也是如此。

以下是使用这些编译指示并使用词汇文件句柄的脚本的清理版本:

#!/usr/bin/perl

use strict;
use warnings;
use autodie;

open my $outfh, ">", "location.txt";
open my $infh1, '<', "./checkins.txt";
open my $infh2, '<', "./locations.txt";

while (my $line1 = <$infh1> and my $line2 = <$infh2>) {
    chomp $line1;
    chomp $line2;
    my @lines1 = split("\t", $line1);
    my @lines2 = split("\t", $line2);

    if ($lines2[0] eq $lines1[5]) {
        print $outfh join("\t", @lines2[0,1,2], @lines1[6,7,8]), "\n";
    }
}
close($outfh);
close($infh1);
close($infh2);
相关问题