簡體   English   中英

Perl腳本在一個公共字段上聯接兩個文件

[英]perl script to join two files on a common field

我正在編寫一個Perl腳本,根據兩個原始文件中的公共字段值將兩個不同文件中的字段連接到第三個新文件中。

我已經編寫了以下腳本,但似乎陷入了無限循環。 關於我需要更改的任何建議?

#!/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);

1990年代打電話來,並希望他們的Perl語法返回...

對於那個很抱歉。 這不是你的錯。

自成立以來,Perl語法已經發生了很大變化,並且由於某些原因,大多數人仍然使用較舊的語法形式進行編寫。 它是在學校里教授的,人們從工作場所中的例子中學到它。 Python開發人員譴責不可讀的 Perl語法,以證明Perl是一種古老的折舊語言,現在屬於歷史垃圾箱。 但是,在許多方面,糟糕的Perl語法證明了學習和學習Perl多么容易。

始終把use strict; use warnings; 在程序的頂部。 這將捕獲Perl中大約90%的錯誤。 while語句中使用=而不是eq== ,將捕獲錯誤。 獲取新版本的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!
}

另外,如果一個文件包含的行比另一個文件多,會發生什么? 我感覺到您想要做的是將一個文件讀入哈希,然后遍歷另一個文件。 如果該哈希鍵存在於第二個文件中,則您希望合並這些行。 不幸的是,您的問題並不清楚您要做什么。

您能否編輯問題以更好地解釋您要完成的任務。 例如,如果您可以為我們提供兩個輸入文件的示例輸入,以及您希望輸出文件的外觀。 您只需要給我們幾行,但這將有助於我們更好地了解您想做什么。

您使用的是Assignment =而不是相等測試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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM