2016-05-07 7 views
0

複数の列に一致させるための2つのタブ区切りテキストファイルがあります。perlは2つのファイルの複数の列名と一致します

これはテーブル1の構造です。可変数のカラムを持つことができます。だから、ヘッダーを使ってtable2と一致させたいです。

a x y b c d z 
1 . . 1 1 1 . 
2 . . 2 2 2 . 
3 . . 6 6 3 . 
4 . . 4 4 4 . 

これはtable2の構造です。行数は常に同じになります。&最初の行は、両方のテーブルから列A、B、C及びDの値との間に一致がある場合さて、私は "列の値を、表2に2つの余分な列を追加したいヘッダ

a b c d e f 
1 1 1 1 yes no 
2 2 2 2 no no 
3 3 3 3 no yes 

です表2から「e」と「f」を選択します。私はに基づいて、ここで試合を行うことができますどのように

私は通常、ハッシュとこの&仕事のためのPerlを使うには、

これは、私はだから私は二つの質問を持っている

my %hash =(); 
while(<$table2>){ 
    chomp; 
    my @cols = split(/\t/); 
    my $keyfield = $cols[0]; 
    my $keyfield2 = $cols[1]; 
    my $keyfield3 = $cols[2]; 
    my $keyfield4 = $cols[3]; 
    push @{ $hash{$keyfield} }, $keyfield2, $keyfield3, $keyfield4; 
    } 
seek $table1,0,0; #cursor resetting 
while(<$table1>){ 
    chomp; 
    my @cols = split(/\t/); 
    my $keyfield = $cols[...]; #how can I make a match here based on the column names 
    if (exists($hash{$keyfield})){ 
     print ... #how can I add two extra columns to the existing $table1? 
    } 
    else { 
     print ... 
    } 
} 

を持っているものです列名

既存の$ table1に2つの余分な列を追加するにはどうすればよいですか?

出力は次のようになります。

a x y b c d z e f 
1 . . 1 1 1 . yes no 
2 . . 2 2 2 . no no 
3 . . 6 6 3 . 'empty' 'empty' 
4 . . 4 4 4 . 'empty' 'empty' 

だから、$ TABLE1には2つの余分な列があり、「E」と「F」からの値との一致がある場合もございます。一致していない場合は空白(値なし)です。

答えて

2

ここでのトリックは、最初のデータをハッシュに読み込み、 'lookup'で 'data'をキー入力することです。

次に参照テーブルを実行します。ハッシュスライスを使用すると、名前付きキーを参照できます。存在する場合;印刷します。そうでない場合は、目的の結果に置き換えてください。 など。

#!/usr/bin/env perl 
use strict; 
use warnings; 

use Data::Dumper; 

open(my $table1, '<', 'data1.txt') or die $!; 
open(my $table2, '<', 'data2.txt') or die $!; 

chomp(my @header = split /\t/, <$table2>); 
my %lookup; 
while (<$table2>) { 
    print; 
    chomp; 
    my @row = split /\t/; 
    #put values into lookup hash, keying on 4 values, to retrieve 'e' and 'f' 
    #could do this like the below, if you wanted to use named values. 
    $lookup{ $row[0] }{ $row[1] }{ $row[2] }{ $row[3] } = [ $row[4], $row[5] ]; 
} 
print Dumper \%lookup; 

#read one line - the header row - and split it into an array. 
chomp(my @header_for_table1 = split /\t/, <$table1>); 
print join "\t", @header_for_table1, "e", "f", "\n"; 
while (<$table1>) { 
    chomp; 
    my %row; 
    @row{@header_for_table1} = split /\t/; 
    print join ("\t", @row{@header_for_table1}, 
         @{ $lookup{ $row{a} }{ $row{b} }{ $row{c} }{ $row{d} } 
          // [ "empty", "empty" ] }), "\n"; 
} 

注://オペレータはperl 5.10+です。この場合は||を使用できますが、ゼロまたは空の文字列が格納されている場合は、少し慎重にしてください。 (0はfalseですが、定義されていますが、これは異なります)。

+0

ニース。代わりに[多次元配列](http://perldoc.perl.org/perldata.html#Multi- dimensional-array-emulation)と同様のアイデアがありました。 '$ e、f => $ f}' '($ ;;" a = 1 "" b = 1 "、" c = 1 "、" d = 1 ")'その値を単純に 'exists'を使って検索します。 – PerlDuck

+0

私は配列とハッシュを最初に使うことについて少し相反していました。何もない限り、一貫性のためです。 – Sobrique

+0

私と同じです。私はまた確信が持てませんでした(そしてまだあります)が、ちょっと、これはPerlです! TISMTOWTDI(またはこの略語は綴られています)。 :-) – PerlDuck

関連する問題