TAGS :Viewed: 8 - Published at: a few seconds ago

[ combine two element in an array perl ]

I want to compare two sequences using standalone blastn.

But before I can do that I have to cut the sequence into 1020nt of each fragment. If the last fragment is less than 1020nt, i have to merge (the sequence) in the last fragment with sequence in the previous fragment . For example I cut a sequence into 1020nt and get 7 fragments. But the 7th fragment is less than 1020nt, so i have to merged it into the 6th fragment. Is anyone know how to do this using Perl language?

This is my code:

while(<QR>){

    chomp;
    s/>//g;

    my ($scaf,$seq)= split /\n/,$_,2;
    my $scaf_name = (split /\s+/,$scaf)[0];
    $seq =~ s/\s+//g;
    my @cut = ($seq =~ /(.{1,$chop_len})/g);

    if (length($#cut) < 1020) {
        $#cut="@cut[-2 .. -1]"; # i get error here
    }
    else {
    }

    print $#cut;
    for my $cut_num (0..$#cut){
        my $sgmID = "$scaf_name\_$cut_num";
        print CR ">$sgmID\n$cut[$cut_num]\n";
    }
}

close QR;
close CR;

Actually I found this Perl script on the internet, and modified it so that I can merged the last two fragments.

Answer 1


You need to remove the last cut and append it to the second-to-last cut using the .= concatenation operator:

Here is a simplified example:

#!/usr/bin/env perl

use warnings;
use strict;

my $total_length = 100;
my $chop_length  = 14;
my @letters = qw( A C G T );

my $long_string = join '', map { $letters[ int rand scalar @letters ] } ( 1 .. $total_length );
print "Long string ($total_length chars) :\n$long_string\n";
print '-'x$total_length . "\n";
my @cut = ($long_string =~ /(.{1,$chop_length})/g);

my $last_cut = pop @cut; # Take last one off
if (length $last_cut < $chop_length) {
    $cut[$#cut] .= $last_cut; # Concatenate it to the (now) last one
} else {
    push @cut, $last_cut; # Put it back, it has the right length
}

print "Parts cut into >= $chop_length char length pieces.\n";
for my $part (@cut) {
    print $part . "\n";
}

Output

Long string (100 chars) :
CCATCCTGCACATTCGGTGATTTATCAGAAGTAAGATCCTCGTCCCACTGACCGTGCGGGGATACGGAGCTCAAACAGAGAGAAACGGTTGGTCTGTAGA
----------------------------------------------------------------------------------------------------
Parts cut into >= 14 char length pieces.
CCATCCTGCACATT
CGGTGATTTATCAG
AAGTAAGATCCTCG
TCCCACTGACCGTG
CGGGGATACGGAGC
TCAAACAGAGAGAA
ACGGTTGGTCTGTAGA

Answer 2


The issue with

if (length($#cut) < 1020) {
    $#cut="@cut[-2 .. -1]"; # i get error here
}

is that it is attempting to assign a string to $#cut. $#cut is the last index of @cut, so it expects an integer value.

Something like this should work:

if (length($#cut) < 1020) {
    $cut[$#cut-1] = join '', @cut[-2 .. -1];
    $#cut -= 1;  # Remove last element from @cut
}