[ 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
}