2012-08-10 35 views
0

這是一個簡單的問題,但找不到任何工作解決方案。我有2個文件,第一個文件包含我感興趣的所有ID,例如「番茄」,「黃瓜」,但也是我不感興趣的,它們在第二個文件中沒有任何價值。第二個文件具有以下數據結構檢索與perl匹配的相同ID的值

tomato red 

tomato round 

tomato sweet 

cucumber green 

cucumber bitter 

cucumber watery 

我需要得到的是包含所有的ID從第二個文件中的所有匹配值的文件,一切選項卡分隔的,就像這樣:

tomato red round sweet 

cucumber green bitter watery 

我做什麼,到目前爲止是創建一個哈希出的第一個文件的ID的:

while (<FILE>) { 
    chomp; 
    @records = split "\t", $_; 
    {%hash = map { $records[0] => 1 } @records}; 
} 

而這第二個文件:

while (<FILE2>) { 
     chomp; 
     @records2 = split "\t", $_; 
     $key, $value = $records2[0], $records2[1]; 
     $data{$key} = join("\t", $value); 
    } 

close FILE; 

foreach my $key (keys %data) 
{ 
    print OUT "$key\t$data{$key}\n" 
    if exists $hash{$key} 
} 

將一些簡單的解決方案組合所有值匹配相同的ID感謝您! :)

回答

1

對日第一個文件:

while (<FILE>) { 
    chomp; 
    @records = split "\t", $_; 
    $hash{$records[0]} = 1; 
} 

和第二:

while (<FILE2>) { 
    chomp; 
    @records2 = split "\t", $_; 
    ($key,$value) = @records2; 
    $data{$key} = [] unless exists $data{$key}; 
    push @{$data{$key}}, $value; 
} 
close FILE; 

foreach my $key (keys %data) { 
    print OUT $key."\t".join("\t", @{$data{$key}})."\n" if exists $hash{$key}; 
} 
+0

是的。同樣值得一讀'perldoc perldsc',它描述了Perl中的數據結構,包括上面使用的散列數組。 – 2012-08-10 11:47:25

+0

非常感謝,Cyber​​Dem0n,它的工作原理應該是:)。謝謝你們,我之前並不熟悉創建哈希數組,現在就來看看吧! – DoubleDecker 2012-08-10 12:06:02

-1

如果先讀出的數據映射它更容易。另外,如果你使用Perl,你應該從一開始就考慮利用它的主要優勢 - CPAN庫。例如,文件的讀入就像從File::Slurp一樣簡單;而不必自己打開/關閉文件,然後運行一段時間(<>)循環。

use File::Slurp; 
my %data; 

my @data_lines = File::Slurp::read_file($filename2); 
chomp(@data_lines); 
foreach my $line (@data_lines) { # Improved version from CyberDem0n's answer 
    my ($key, $value) = split("\t", $line); 
    $data{$key} ||= []; # Make sure it's an array reference if first time 
    push @{ $data{$key} }, $value; 
} 

my @id_lines = File::Slurp::read_file($filename1); 
chomp(@id_lines); 
foreach my $id (@id_lines) { 
    print join("\t", ($id, @{ $data{$id} }))."\n"; 
} 

一個稍微哈克但有點短的代碼將標識以值的數據散列從列表中得到去:

my @data_lines = File::Slurp::read_file($filename2); 
chomp(@data_lines); 
foreach my $line (@data_lines) { # Improved version from CyberDem0n's answer 
    my ($key, $value) = split("\t", $line); 
    $data{$key} ||= [ $id ]; # Add the ID for printing 
    push @{ $data{$key} }, $value; 
} 

my @id_lines = File::Slurp::read_file($filename1); 
chomp(@id_lines); 
foreach my $id (@id_lines) { 
    print join("\t", @{ $data{$id} }) ."\n"; # ID already in %data! 
} 
+0

爲什麼downvote? – DVK 2012-08-10 20:46:45

0

這似乎做什麼是需要

use strict; 
use warnings; 

my %data; 

open my $fh, '<', 'file1.txt' or die $!; 
while (<$fh>) { 
    $data{$1} = {} if /([^\t]+)/; 
} 

open $fh, '<', 'file2.txt' or die $!; 
while (<$fh>) { 
    $data{$1}{$2}++ if /^(.+?)\t(.+?)$/ and exists $data{$1}; 
} 

while (my ($key, $values) = each %data) { 
    print join("\t", $key, keys %$values), "\n"; 
} 

輸出

tomato sweet round red 
cucumber green watery bitter 
是的,