2012-10-30 43 views
2

我有這個文件檢查,如果數量在兩個值

427 A C A/C 12 
436 G C G/C 12 
445 C T C/T 12 
447 A G A/G 9 
451 T C T/C 5 
456 A G A/G 12 
493 G A G/A 12 

我想讀的第一列,找到所有其他ID它們小於10

427 A C A/C 12 436 
436 G C G/C 12 427,445 
445 C T C/T 12 436,447,451 
447 A G A/G 9 445,451,456 
451 T C T/C 5 445,447,456 
456 A G A/G 12 451,447 
493 G A G/A 12 

的差異之間最後一欄應該像上面那樣。所有的ID都是+或 - 與該特定ID相隔10個鹼基。例如,對於436,其邊界是{426-446}其他ID在427和445範圍內,因此我將它們顯示在第6列中。

+0

所以,你開始在Perl這樣做,awk或者sed,並被困在什麼時候? – John3136

+0

這實際上是一個大代碼的一部分,我感到很震驚。作爲一個新手,我不知道我怎麼能做到這一點。我能夠在Excel中做到這一點,但因爲我想自動執行此操作,並保留作爲我的其他代碼的一部分。任何幫助? – user630605

回答

3

這是一個使用Perl的一種方式:

use strict; 
use warnings; 

open my $fh, '<', 'dataFile.txt' or die $!; 
chomp(my @data = <$fh>); 
close $fh; 

my @IDs = map /(\d+)/, @data; 

for (@data) { 
    my ($id) = /(\d+)/; 
    print "$_\t" 
     . (join ',', grep { abs $id - $_ < 11 and $id != $_ } @IDs) 
     . "\n"; 
} 

輸出:

427 A C A/C 12 436 
436 G C G/C 12 427,445 
445 C T C/T 12 436,447,451 
447 A G A/G 9 445,451,456 
451 T C T/C 5 445,447,456 
456 A G A/G 12 447,451 
493 G A G/A 12 
2

以下是使用GNU awk的一種方法。的script.awk

awk -f script.awk file.txt{,} | column -t 

內容:

FNR==NR { 
    array[$1]++ 
    next 
} 

{ 
    n = asorti(array,sort) 

    for (i=1; i<=n; i++) { 

     if (sort[i] <= $1 + 10 && sort[i] >= $1 - 10 && $1 != sort[i]) { 
      line = (line ? line "," : line) sort[i] 
     } 
    } 

    print $0, line 

    line = "" 
} 

結果:像運行

427 A C A/C 12 436 
436 G C G/C 12 427,445 
445 C T C/T 12 436,447,451 
447 A G A/G 9 445,451,456 
451 T C T/C 5 445,447,456 
456 A G A/G 12 447,451 
493 G A G/A 12 

另外,這裏是一個班輪:

awk 'FNR==NR { array[$1]++; next } { n = asorti(array,sort); for (i=1; i<=n; i++) if (sort[i] <= $1 + 10 && sort[i] >= $1 - 10 && $1 != sort[i]) line = (line ? line "," : line) sort[i]; print $0, line; line = "" }' file.txt{,} | column -t