2013-03-07 59 views
0

我遇到了一些小故障。我有2個文件,這是這樣的:Perl:從第一個文件中比較第二個文件的2個文件和打印值的數值

文件1

chr10 179423 181499 181423 2076 + NM_001202464 ZMYND11 
chr10 693887 696118 695887 2231 + NR_027151 C10orf108 
chr10 694016 696382 696016 2366 + NR_027152 C10orf108 
chr10 1032348 1034467 1034348 2119 + NM_GTPBP4 
chr10 1203707 1205930 1205707 2223 + NR_015376 LINC00200 

文件2

chr10 176225 
chr10 180990 
chr10 181315 
chr10 181529 
chr10 181695 
chr10 182183 
chr10 686673 
chr10 686699 
chr10 688273 
chr10 695323 
chr10 698323 
chr10 722737 
chr10 906075 
chr10 908409 
chr10 928052 
chr10 950429 
chr10 989722 
chr10 1006348 
chr10 1010731 
chr10 1020229 
chr10 1034526 
chr10 1064089 
chr10 1103000 
chr10 1103198 
chr10 1103267 
chr10 1114980 
chr10 1135327 
chr10 1150625 
chr10 1193412 
chr10 1193677 
chr10 1199817 
chr10 1212181 
chr10 1212310 
chr10 1216875 
chr10 1218919 
chr10 1226134 
chr10 1226254 

需要什麼

去行方向,爲每一位4th elementFile1打印從File2出其值是>= 2nd element from file1 & <= (4th element from file1+2000)

因此,例如,在File1,在row1第四元件是。 File2的值爲:>= 2nd element from file1(179423)<= 4th element from file1+2000(183423)是18090,181315,181529,181695,182183。

如果找不到值,應打印NA

所需的輸出

製表符分隔的文件,該文件是這樣的:

chr10 179423 181423 183423 NM_001202464 ZMYND11  180990 
                  181315 
                  181529 
                  181695 
                  182183 
chr10 693887 695887 697887 NR_027151 C10orf108  695323 
chr10 694016 696016 698016 NR_027152 C10orf108  695323 
chr10 1032348 1034348 1036348 NM_GTPBP4   1034526 
chr10 1203707 1205707 1207707 NR_015376 LINC00200  NA 

我的代碼

我就如何去做毫無本事。起初,有人告訴我,我只需要找到file22nd4th元素file1之間的值。爲此,我使用散列編寫了以下代碼,雖然這些代碼雖然有效,但並未完成全部工作。 (在if循環的&&部分沒有做什麼,我認爲應該,所以正在打印的所有較大的值)

下面這段代碼是完全無用的:/我在我束手無策,因爲我不知道如果在3個月內進入Perl編程,我應該能夠編寫狡猾的程序。

use 5.014; 
use warnings; 

#Assign filenames 
my $file1 = 'file1.txt' || die $!; #File with TSS coordinates 
my $file2 = 'file2.txt' || die $!; #File with G4 coordinates 

#Open files 
open my $fh1, '<' , $file1 || die $!; 
open my $fh2, '<' , $file2 || die $!; 

#Open output 
open OUT, ">G4_coordinates_promoters$file1.out" || die $!; 

#Read files 
while (<$fh1>) { 
    chomp; 
    my %data1; #Hash for TSS 
    my ($key1, $val1) = (split) [1,3]; 
    $data1{$key1} = $val1; 
    while (<$fh2>) { 
     chomp ; 
     my %data2; #Hash for G4 coordinates 
     my ($key2, $val2) = (split) [1,2]; 
     $data2{$key2} = $val2; 

     #Compare hashes 
     if (($key2 > $key1) && 
      ($key2 << $data1{$key1})){ #Here the code after && is NOT working 
      say OUT $key2 
     } 
    } 
} 

謝謝你去通過我的問題。如果能找到解決這個問題的簡單方法,我將不勝感激。

+0

愛在'exit'的'#Exit'評論! – Borodin 2013-03-07 10:51:43

+0

@Borodin謝謝你,先生!我嘗試標記我的代碼部分,以便我知道每個區域在做什麼,即使有些可能非常明顯。 – Neal 2013-03-07 10:55:39

+0

@Neal你知道你的'死'陳述永遠不會發生,對吧?因爲''字符串''總是正確的,所以'||'運算符的優先級比逗號運算符的優先級高,並且還有短路。 – TLP 2013-03-07 10:59:31

回答

3

這個程序似乎做你所需要的。

輸出是以製表符分隔的格式寫入的 - 與輸入數據相同 - 因此延續行具有正確數量的製表符,但不與實際行首行對齊。如果你想要不同的東西,請說出來。

file2中的所有值都被拉入數組@file2並從那裏進行處理。該代碼假定這些值已經排序。

while (<$fh>) { 
    chomp; 
    my @fields = split /\t/; 

    my $min = $fields[1]; 
    my $max = $fields[3] + 2000; 

    my @values; 
    for my $val (@file2) { 
    last if $val > $max; 
    push @values, $val if $val >= $min; 
    } 
    push @values, 'NA' unless @values; 

    for my $val (@values) { 
    print join("\t", @fields, $val), "\n"; 
    $_ = '' for @fields; 
    } 
} 

輸出

chr10 179423 181499 181423 2076 + NM_001202464 ZMYND11 180990 
       181315 
       181529 
       181695 
       182183 
chr10 693887 696118 695887 2231 + NR_027151 C10orf108 695323 
chr10 694016 696382 696016 2366 + NR_027152 C10orf108 695323 
chr10 1032348 1034467 1034348 2119 + NM_GTPBP4 1034526 
chr10 1203707 1205930 1205707 2223 + NR_015376 LINC00200 NA 
+0

你好,先生!再次感謝您提供簡單的方法。只需要再做一次修改。我需要爲沒有找到值的條目打印「NA」。我怎麼做? – Neal 2013-03-07 11:54:16

+0

如果我正確理解這行代碼,'@ _ =''for @fields;',那麼''''會在找到多個值時置空行? – Neal 2013-03-07 12:06:05

+1

我已經爲您的新要求修改了我的答案。 '@ _ =''for @ fields'將所有字段設置爲一個空字符串,以便這些值不會打印在多行上(但正確數量的製表符*是*輸出)。 – Borodin 2013-03-07 12:11:30

相關問題