如果第二个字段匹配,perl使用一行程序将列添加到文件中
我有一个文件,有些行有4个字段,有些行有3个字段,如下所示:如果第二个字段匹配,perl使用一行程序将列添加到文件中,perl,Perl,我有一个文件,有些行有4个字段,有些行有3个字段,如下所示: 1 rs17125090 63988904 ENSG00000142856 7 7.87455705 ENSG00000075303 在该行有3个字段的情况下,第二个字段与“number.longer number”匹配,而在该行有4个字段的情况下,第二个字段与“rsnumber”匹配。在该行有3个字段的情况下,我想在第三列中添加一个字段,该字段包含一个等于第二个字段的数字,以“.”分隔。例如,生成的文件如下所示: 1 rs1712
1 rs17125090 63988904 ENSG00000142856
7 7.87455705 ENSG00000075303
在该行有3个字段的情况下,第二个字段与“number.longer number”匹配,而在该行有4个字段的情况下,第二个字段与“rsnumber”匹配。在该行有3个字段的情况下,我想在第三列中添加一个字段,该字段包含一个等于第二个字段的数字,以“.”分隔。例如,生成的文件如下所示:
1 rs17125090 63988904 ENSG00000142856
7 7.87455705 87455705 ENSG00000075303
我的perl一行是:
perl -e 'for(`cat file`){my@L=split;if($L[1]=~m/^\d+\.\d+$/){my@snp=split(/\./,$L[1]);splice(@L,2,0,$snp[1])}}open OUT,">file.new";print OUT "@L\n"; close OUT'
但我只是得到一个空文件。有人能解决这个问题/告诉我出了什么问题吗?编写单行程序时需要非常小心。许多正常的保护措施都没有到位,而且在没有布局的情况下,发现错误的难度要小得多 你的代码相当于这个程序
for ( `cat file` ) {
my @L = split;
if ( $L[1] =~ m/^\d+\.\d+$/ ) {
my @snp = split( /\./, $L[1] );
splice( @L, 2, 0, $snp[1] );
}
}
open OUT, ">file.new";
print OUT "@L\n";
close OUT;
你现在能看到问题在哪里吗
这应该可以满足你的需要
perl -anE 'splice @F, 2, 0, $F[1] =~ /\.(\d+)/; say "@F";' myfile
这将有助于你展示一个可读的程序版本。谢谢你对我(现在已删除)的答案的评论。我说“for循环体只运行一次”,您更正了这一点:“cat文件输出中的每行循环体运行一次。”(我不知道backticks在列表上下文中的行为是这样的。)我还发布了一个由于复制和粘贴错误而损坏的修复版本。它应该说:[perl-pe“s/\(\d+/$1$1/”file.new]@Buster:还要注意,在perl替换的替换字符串中应该使用
$1
,而不是\1
。这个解决方案可能没问题,但我们不知道行中的其他地方没有任何其他点字符会导致失败。在我上面的评论中,“修复”指的是使用$1而不是\1,不是第二个批评,这是您后来添加的,也是正确的。