解析simiiar制表符分隔文件的相同代码的不同输出

时间:2017-05-01 13:09:46

标签: perl shell

下面的Perl脚本是用shell编写的。

如果我使用制表符分隔的文件numeric,那么我会得到相应解析的每行的所需结果。但是,如果我使用文件alpha作为输入,则只解析第一行。

alphanumeric之间的唯一区别是numericNC_000023

NC_000023.11:g.41747805_41747806delinsTT
NC_000023.11:g.41750615C>A

alphaNC_0000X

NC_0000X.11:g.41747805_41747806delinsTT
NC_0000X.11:g.41750615C>A

我错过了什么?

数字

Input Variant   Errors  Chromosomal Variant Coding Variant(s)
NM_003924.3:c.*18_*19delGCinsAA     NC_000023.11:g.41747805_41747806delinsTT    LRG_513t1:c.*18_*19delinsAA NM
NM_003924.3:c.013G>T        NC_000023.11:g.41750615C>A  LRG_513t1:c.13G>T   

的α

Input Variant   Errors  Chromosomal Variant Coding Variant(s)
NM_003924.3:c.*18_*19delGCinsAA     NC_0000X.11:g.41747805_41747806delinsTT LRG_513t1:c.*18_*19delinsAA NM_003924.3:c.*18_*19delinsAA
NM_003924.3:c.013G>T        NC_0000X.11:g.41750615C>A   LRG_513t1:c.13G>T   NM_003924.3:c.13G>T

的Perl

perl -ne '

next if $. == 1;

if ( /.*del([A-Z]+)ins([A-Z]+).*NC_0+([^.]+)\..*g\.([0-9]+)_([0-9]+)/ ) { # indel
    print join( "\t", $3, $4, $5, $1, $2 ), "\n";
}
else {

    while ( /\t*NC_(\d+)\.\S+g\.(\d+)(\S+)/g ) {

        # conditional parse

        ( $num1, $num2, $common ) = ( $1, $2, $3 );
        $num3 = $num2;

        if ( $common =~ /^([A-Z])>([A-Z])$/ ) {      # SNP
            ( $ch1, $ch2 ) = ( $1, $2 );
        }
        elsif ( $common =~ /^del([A-Z])$/ ) {        # deletion
            ( $ch1, $ch2 ) = ( $1, "-" );
        }
        elsif ( $common =~ /^ins([A-Z])$/ ) {        # insertion
            ( $ch1, $ch2 ) = ( "-", $1 );
        }
        elsif ( $common =~ /^_(\d+)del([A-Z]+)$/ ) { # multi deletion
            ( $num3, $ch1, $ch2 ) = ( $1, $2, "-" );
        }
        elsif ( $common =~ /^_(\d+)ins([A-Z]+)$/ ) { # multi insertion
            ( $num3, $ch1, $ch2 ) = ( "-", $1, $2 );
        }

        printf( "%d\t%d\t%d\t%s\t%s\n", $num1, $num2, $num3, $ch1, $ch2 ); # output

        map { undef } ( $num1, $num2, $num3, $common, $ch1, $ch2 );
    }
}' numeric

输出

23  41747805    41747806    GC  AA
23  41750615    41750615    C   A

使用alpha输出

X   41747805    41747806    GC  AA

如果我在\w条件中使用\d而不是while,就像这样

while ( /\t*NC_(\w+)\.\S+g\.(\d+)(\S+)/g ) { ... }

我得到了这个结果

X   41747805    41747806    GC  AA
0   41750615    41750615    C   A

为什么$1

中的零

1 个答案:

答案 0 :(得分:2)

while (/\t*NC_(\d+)\.与'NC_0000X.11'不匹配,因为'X'而且正则表达式只查找数字。

完成更改后,NC_(\w+)将匹配“NC_0000X”,$num1设置为“0000X”。

您的printf "%d...." $num1 ...将为非数字输入打印0。当$num1为'0000X'时,它将打印为0.

输入示例表明,每一行都由字段组成,这些字段由空格分隔。有些领域是有意义的,不是。每个字段都包含可识别的信息。

您的程序应遵循此结构。

  • 逐行阅读文件
  • 将该行拆分为字段
  • 跳过不感兴趣的字段,例如非NC。*
  • 从字段中提取必要的信息
  • 做任何必要的事情,总结一下,收集它
  • 在所需级别打印信息。每个字段,行,文件或所有文件

在较小的chuncks上工作更容易,而不是找到适用于整个生产线的正则表达式。它更容易阅读,理解和维护。