2012-09-11 104 views
0

我是相當新的Perl的,所以希望這有一個快速的解決方案。合併基於第一列兩個文件,並返回多個值,每個鍵

我一直在試圖基於一個關鍵的兩個文件合併。問題是有多個值而不是它返回的值。有沒有辦法通過哈希循環來獲得更多的值?

例子:

文件輸入1:

12345|AA|BB|CC 
23456|DD|EE|FF 

文件輸入2:

12345|A|B|C 
12345|D|E|F 
12345|G|H|I 
23456|J|K|L 
23456|M|N|O 
32342|P|Q|R 

我把上面提到的最後一個原因是因爲第二個文件有很多值的我不想但文件1我想要所有的值。我要的結果是這樣的:

WANTED OUTPUT:

12345|AA|BB|CC|A|B|C 
12345|AA|BB|CC|D|E|F 
12345|AA|BB|CC|G|H|I 
23456|DD|EE|FF|J|K|L 
23456|DD|EE|FF|M|N|O 

附件是我目前使用的代碼。它給出了一個輸出像這樣:

OUTPUT我越來越:

12345|AA|BB|CC|A|B|C 
23456|DD|EE|FF|J|K|L 

我迄今爲止代碼:

#use strict; 
#use warnings; 

open file1, "<FILE1.txt"; 
open file2, "<FILE2.txt"; 

while(<file2>){ 

    my($line) = $_; 
    chomp $line; 
    my($key, $value1, $value2, $value3) = $line =~ /(.+)\|(.+)\|(.+)\|(.+)/; 
    $value4 = "$value1|$value2|$value3"; 
    $file2Hash{$key} = $value4; 
} 

while(<file1>){ 

    my ($line) = $_; 
    chomp $line; 
    my($key, $value1, $value2, $value3) = $line =~/(.+)\|(.+)\|(.+)\|(.+)/; 

    if (exists $file2Hash{$key}) { 

     print $line."|".$file2Hash{$key}."\n"; 
    } 
    else { 
     print $line."\n"; 
    } 
} 

感謝您的幫助,您可以提供,

+2

它看起來像你完全正確的思路上來,除非你需要處理以相反的順序文件1和文件2! – hobbs

回答

2

你的總體思路是合理的。但是,在file2中,如果遇到已定義的密鑰,則用新值覆蓋它。爲了解決這個問題,我們在我們的哈希中存儲一個數組(-ref)。

所以在你的第一個循環,我們這樣做:

push @{$file2Hash{$key}}, $value4; 

@{...}只是數組語法句法。

在你的第二個循環中,我們做到:

if (exists $file2Hash{$key}){ 
    foreach my $second_value (@{$file2Hash{$key}}) { 
    print "$line|$second_value\n"; 
    } 
} else { 
    print $line."\n"; 
} 

除此之外,你可能要申報%file2Hashmy這樣你就可以重新激活strict

+0

謝謝你的迴應!這工作!我得到了我以前沒有得到的所有價值!謝謝! – user1258104

1

鍵在散列必須是唯一的。如果file1中的密鑰是唯一的,則使用file1創建散列。如果鍵不是在任何文件中獨一無二的,你必須使用更復雜的數據結構:在每一個獨特的按鍵排列的哈希值,即存儲幾個值。

0

我假定在每個FILE1.TXT關鍵是獨一無二的,並且每個獨特密鑰具有在FILE2.TXT至少一個相應的行。

你的做法是那麼相當接近,你需要什麼,你應該只使用FILE1.TXT創建從散列(如已經提到here)。

下面應該工作:

#!/usr/bin/perl 

use strict; 
use warnings; 

my %file1hash; 

open file1, "<", "FILE1.txt" or die "$!\n"; 
while (<file1>) { 
    my ($key, $rest) = split /\|/, $_, 2; 
    chomp $rest; 
    $file1hash{$key} = $rest; 
} 
close file1; 

open file2, "<", "FILE2.txt" or die "$!\n"; 
while (<file2>) { 
    my ($key, $rest) = split /\|/, $_, 2; 
    if (exists $file1hash{$key}) { 
     chomp $rest; 
     printf "%s|%s|%s\n", $key, $file1hash{$key}, $rest; 
    } 
} 
close file2; 

exit 0; 
相關問題