将2个文件中的行传递到相同的子例程

时间:2014-09-24 09:23:32

标签: perl subroutine fastq

我正在学习如何将perl用于基因组学应用。我正在尝试清理成对的结束读取(1个正向,1个反向)。它们存储在2个文件中,但行匹配。我正在做的就是从第二个文件中读取相关的子程序(我得到的警告是未初始化的值)。

这些文件设置为4个行块(fastq),其中第一行是运行ID,第二行是序列,第三行是“+”,第四行包含第2行中序列的质量值。 / p>

这个代码只应用于一个文件时没有真正的麻烦,但我想我误解了如何处理多个文件。

非常感谢任何指导!

我在这种情况下的警告是这样的:在./pairedendtrim.pl第137行第4行的减法( - )中使用未初始化的值$ thisline。

#!/usr/bin/perl
#pairedendtrim.pl by AHU
use strict;
use warnings;

die "usage: readtrimmer.pl <file1> <file2> <nthreshold> " unless @ARGV == 3;
my $nthreshold = "$ARGV[2]";

open( my $fastq1, "<", "$ARGV[0]" );
open( my $fastq2, "<", "$ARGV[1]" );

my @forline;
my @revline;
while ( not eof $fastq2 and not eof $fastq1 ) {
    chomp $fastq1;
    chomp $fastq2;
    $forline[0] = <$fastq1>;
    $forline[1] = <$fastq1>;
    $forline[2] = <$fastq1>;
    $forline[3] = <$fastq1>;

    $revline[0] = <$fastq2>;
    $revline[1] = <$fastq2>;
    $revline[2] = <$fastq2>;
    $revline[3] = <$fastq2>;

    my $ncheckfor = removen( $forline[1] );

    my $ncheckrev = removen( $revline[1] );

    my $fortest = 0;
    if ( $ncheckfor =~ /ok/ ) { $fortest = 1 }

    my $revtest = 0;

    if ( $ncheckrev =~ /ok/ ) { $revtest = 1 }

    if ( $fortest == 1 and $revtest == 1 ) { print "READ 1 AND READ 2" }

    if ( $fortest == 1 and $revtest == 0 ) { print "Read 1 only" }

    if ( $fortest == 0 and $revtest == 1 ) { print "READ 2 only" }

}

sub removen {
    my ($thisline) = $_;
    my $ntotal = 0;
    for ( my $i = 0; $i < length($thisline) - 1; $i++ ) {
        my $pos = substr( $thisline, $i, 1 );
        #print "$pos\n";
        if ( $pos =~ /N/ ) { $ntotal++ }
    }
    my $nout;
    if ( $ntotal <= $nthreshold )    #threshold for N
    {
        $nout = "ok";
    } else {
        $nout = "bad";
    }
    return ($nout);
}

1 个答案:

答案 0 :(得分:0)

子程序的参数位于@_,而不是$_

sub removen {
    my ($thisline) = @_;

我还有一些其他提示:

  1. use autodie;只要您正在进行文件处理。
  2. 首先将@ARGV中的值分配给变量。这很快就记录下了什么。
  3. 不要chomp文件句柄。这没有任何作用。而是将chomp应用于从阅读中返回的值。
  4. 不要将字符串okbad用作布尔值。
  5. tr可用于计算字符在字符串中的次数。
  6. 以下是代码的清理版本:

    #!/usr/bin/perl
    #pairedendtrim.pl by AHU
    use strict;
    use warnings;
    use autodie;
    
    die "usage: readtrimmer.pl <file1> <file2> <nthreshold> " unless @ARGV == 3;
    
    my ( $file1, $file2, $nthreshold ) = @ARGV;
    
    open my $fh1, '<', $file1;
    open my $fh2, '<', $file2;
    
    while ( not eof $fh2 and not eof $fh1 ) {
        chomp( my @forline = map { scalar <$fh1> } ( 1 .. 4 ) );
        chomp( my @revline = map { scalar <$fh2> } ( 1 .. 4 ) );
    
        my $ncheckfor = removen( $forline[1] );
        my $ncheckrev = removen( $revline[1] );
    
        print "READ 1 AND READ 2" if $ncheckfor  and $ncheckrev;
        print "Read 1 only"       if $ncheckfor  and !$ncheckrev;
        print "READ 2 only"       if !$ncheckfor and $ncheckrev;
    }
    
    sub removen {
        my ($thisline) = @_;
        my $ntotal = $thisline =~ tr/N/N/;
        return $ntotal <= $nthreshold;    #threshold for N
    }