【发布时间】:2017-05-01 13:09:45
【问题描述】:
下面的 Perl 脚本是用 shell 编写的。
如果我使用制表符分隔文件numeric,那么我会得到相应解析的每一行的所需结果。但是,如果我使用文件 alpha 作为输入,那么只会解析第一行。
alpha 和 numeric 之间的唯一区别是 numeric 有 NC_000023
NC_000023.11:g.41747805_41747806delinsTT
NC_000023.11:g.41750615C>A
而alpha 有NC_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
如果我在while 条件中使用\w 而不是\d,就像这样
while ( /\t*NC_(\w+)\.\S+g\.(\d+)(\S+)/g ) { ... }
我得到了这个结果
X 41747805 41747806 GC AA
0 41750615 41750615 C A
为什么$1 中的零
【问题讨论】:
-
您在标题中提到制表符分隔,但您的文件中没有制表符。而且你没有对标签做任何事情。在
while (/\t*旁边,这在那时是无用的,因为\t是否在输入中并不重要。 -
您的代码布局非常糟糕,难以阅读。如果您想对自己这样做,我可以,但如果您向世界其他地方寻求免费帮助,那么努力并展示一些清晰的东西会更合适。您还必须在您编写的每个程序的顶部始终
use strict和use warnings 'all'。在您指望他人修复您的代码之前,它们将帮助您发现任何微不足道的错误。 -
@ULick:请写下您的第一条评论作为答案。
-
您的第一个正则表达式会选择其中包含
del.*ins(我简化了它)的行。我认为很可能,您在 else 部分找不到四个正则表达式之一。取决于你的真实输入。至少对于输入示例,这部分是无用的。