2012-10-30 42 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