2015-02-10 71 views
-5

參考文件如何比較和合並多個文件?

chr1 288598 288656 

chr1 779518 779576 

chr2 2569592 2569660 

chr3 5018399 5018464 

chr4 5182842 5182882 

文件1

chr1 288598 288656 12 

chr1 779518 779576 14 

chr2 2569592 2569660 26 

chr3 5018399 5018464 27 

chr4 5182842 5182882 37 

文件2

chr1 288598 288656 35 

chr2 2569592 2569660 348 

chr3 5018399 5018464 4326 

chr4 5182842 5182882 68 

我不提及文件6個類似的文件。

這裏前三個字段與參考文件相似。因此,我想從所有6個文件中僅導出第4列,並將其放入參考文件以創建新的輸出。這應該等同於參考文件。他們不匹配的地方把零。

期望的輸出

chr1 288598 288656 23 35 57 68 769 68 

chr1 779518 779576 23 0 57 68 768 0 

chr2 2569592 2569660 23 35 0 68 79 0 

chr3 5018399 5018464 0 36 0 68 769 0 

chr4 5182842 5182882 23 0 0 0 0 0 

注:參考文件長度爲約2000 ANS的其它文件不總是在相同的長度(約500,400,200,100等)。這就是爲什麼需要添加零。

我想答案從this question

paste ref.file file1 file2 file3 file4 file5 file6 | awk '{OFS="\t";print $1,$2,$3,$7,$11,$15,$19,$23,$27}' > final.common.out 

,但似乎它不工作 - 一些值被錯過。我無法理解如何在沒有匹配的地方添加零。

+0

提示:看看join命令。 – SMA 2015-02-10 16:10:13

+1

文件中是否真的有空行?我不假設,但你爲什麼要這樣展示他們? – Borodin 2015-02-10 17:13:28

+0

沒有抱歉.....沒有空白。 – unique379 2015-02-10 17:54:30

回答

1

我覺得像這樣應該做你想做的。我們使用散列來收集'參考'文件,並將其變成一組具有空數組的鍵。

然後我們迭代其他文件,提取'3值'作爲關鍵字,最後一個值作爲實際值。

然後我們比較兩者,用值或零更新'reference'散列。這裏需要注意的是 - 參考文件(或重複項)中的任何行而不是將會消失。

#!/usr/bin/perl 

use strict; 
use warnings; 
use autodie; 


#read 'reference file' into a hash: 
my %ref; 
open(my $ref_fh, "<", "reference_file"); 
while (<$ref_fh>) { 
    my ($first, $second, $third) = split; 

    #turn the first three fields into space delimited key. 
    $ref{"$first $second $third"} =(); 
} 

#open each of the files. 
my @files = qw (file1 file2 file3 file4 file5 file6); 
foreach my $input (@files) { 
    open(my $input_fh, "<", $input); 
    my %current; 
    while (<$input_fh>) { 

     #line by line, extract 'first 3 fields' to use as a key. 
     #then 'value' which we store. 
     my ($first, $second, $third, $value) = split; 
     $current{"$first $second $third"} = $value; 
    } 

    #refer to 'reference file' and insert matching value or zero into 
    #the array. 
    foreach my $key (keys %ref) { 
     push(@{ $ref{$key} }, $current{$key} ? $current{$key} : 0); 
    } 
} 

foreach my $key (keys %ref) { 
    print join(" ", $key, @{ $ref{$key} }); 
} 
+0

非常感謝你的漂亮的代碼,它的工作很好,但出來需要一個新的路線,每場比賽。因爲它的全部在一條線上。 – unique379 2015-02-11 13:46:33

+0

非常感謝你爲你的漂亮的代碼,它的工作很好,但出來需要一個新的線和每個比賽的選項卡。但是,我已經完成了。 再次感謝您寶貴的時間和幫助。 – unique379 2015-02-11 13:59:12