从序列中删除给定范围的字母
FILE1
1 MSSNSDTGDLQESLKHGLTPI GAGLPDRHGSPIPARGRLVML PKVETEALGLARSH 2 MHSSNPKVRSSPSGNTQSSPK SKQEVMVRPPTVMSPSGNPQL DSKFSN 3 MNGHSDEESVRNSSGESSQSD DDSGSASGSGSGSSSGSSSDG S
FILE2
1 9 24 36 40
2 1 14 19 35
3 8 37
期望的输出
文件2包含制表符分隔的数字,所有行中的每两个数字是需要从相应序列(制表符分隔文件1)中删除的字母范围。 例如对于序列1,我需要打印1到8 (不是9到24) ,25到35 (不是36到40)和41到41的结束的字母。
我的代码(不完美)
#!usr/bin/perl -w use warnings; open( FH, "a.txt" ); @seq = <FH>; open( FH1, "b.txt" ); @num = <FH1>; open( OUT, ">out.txt" ); @seqs = split( /\n/, "@seq" ); @nums = split( /\n/, "@num" ); foreach $new (@nums) { @num1 = split( '\t', $new ); $n1 = $num1[1]; $n2 = $num1[2]; $n3 = $num1[3]; $n4 = $num1[4]; } foreach $old (@seqs) { @seq1 = split( '\t', $old ); $len = @seq1; print OUT"@seq1[0..$n1,$n2..$n3,$n4..$len]"; } close FH; close FH1; close OUT;
注意:原始文件要大得多,拆分可能会失去内存
首先,总是使用use warnings;
use strict;
。 use Data::Dumper;
真的会帮你在这里
另外,您可以从您的shebang行删除多余的-w (warnings)
标志。
> original files are much much larger and split may go out of memory
你不应该把整个文件读入内存: @array = <FH>;
相反,你应该一行行: while (my $line = <$FH>) {
这给我们带来了另一个问题…你应该使用3-arg词法范围的open
。
open my $fh, ">", $file;
接下来的事情, @nums = split( /\n/, "@num");
有几个问题。
- 失去variables周围的引号。
- @nums将包含行数,就是这样。
所以,一旦你已经修复所有这一切….
你的逻辑在foreach
循环中看起来不对。
当文件中每行的内容不相同时,为什么要硬编码4个值? 在最后一遍的意义上,只有2个值,你从split
分配4。
似乎你的意思是同时在每个arrays上操作…
例如,
# While array != null # # read nums array for indecies to skip # # grab same row of data to print missing values you want skipped # # print data to output file... # end
说实话,我会修改/重写这整个脚本。 如果还有问题,请回到这里。