http://www.perlmonks.org?node_id=1030490


in reply to Re^3: How can one get all possible combinations of elements of different arrays using File::Glob(bsd_glob)?
in thread How can one get all possible combinations of elements of different arrays using File::Glob(bsd_glob)?

Hi hdb,

Thanks for the code snippets and update. Honestly speaking, I do not understand exactly where I have to make the changes in my script with the codes given by you in update for getting correct results from the script. I think I have to read more about the use of File::glob perl module and look for examples online to understand the stuff. Using the code given by you I have found that the cmd shows the result {C1G1,C1G2,C2G1}. I find it difficult how to use this in my script to solve the problem.

With kind regards,

Here goes the output of cmd:

Microsoft Windows [Version 6.1.7600] Copyright (c) 2009 Microsoft Corporation. All rights reserved. C:\Users\x>cd desktop C:\Users\x\Desktop>t9.pl {C1G1,C1G2,C2G1} C:\Users\x\Desktop>t9.pl

Replies are listed 'Best First'.
Re^5: How can one get all possible combinations of elements of different arrays using File::Glob(bsd_glob)?
by poj (Abbot) on Apr 24, 2013 at 20:33 UTC
    Here are 11 changes/simplifications to make your script work
    #!/usr/bin/perl #1 add use strict use strict; use warnings; #2 add '' use File::Glob('bsd_glob'); #3 declare variables my (@array,@DNA,@list); my ($filename,$combi,$entry,$number,$DNA); do { #4 not needed @array=@array1; print"\n\n Press 1 to Enter New File or 2 to Combine: "; $entry=<STDIN>; chomp $entry; if ($entry==1) { print"\n\n Enter New File Name (.txt): "; $filename = <STDIN>; chomp $filename; unless ( open(FILE, $filename) ) { print "Cannot open file \"$filename\"\n\n"; exit; } @DNA= <FILE>; close FILE; #5 add chomp chomp(@DNA); #6 add join by comma $DNA = join(',',@DNA); push @array, $DNA; #7 not needed @array1=@array; } elsif ($entry==2) { #8 @array1 not needed use @array #@array1=@array; # Curly brace for entry2 starts $number=@array; print"\n\n No. of Elements in Joined Array: $number\n"; print"\n Joined Array:\n"; print "@array\n"; #9 none of this code required because comma added a #6 # Use of foreach LOOP to view each element of joined array: #num=0; #foreach my $element (@array1) { # $num++; # print"\n Array No.$num of the Joined Array:\n"; # print $element; # print"\n"; # Code to surround each element of joined array # followd by comma i.e. [ ], # @element=split('',$element); # $str1 = sprintf '[%s],'x @element,@element; # print"\n str1: $s\n"; #push @ARRAY1,$element; #} # Curly brace for foreach ends: #print"\n ARRAY:\n"; #print @ARRAY1; #print"\n"; # To produce all possible combinations of different elements: #10 use simple $_ on @array #$combi = join('',map {'{'.join (',',@$_).'}'} @ARRAY1); $combi = join('',map {'{'.$_.'}'} @array); print "combi = $combi\n"; @list = bsd_glob($combi); print"\n Results:\n"; #11 print each element on new line print join "\n",@list; } # Curly brace for Entry 2 ends: } until ($entry==2); # Square bracket for do-until: exit;
    poj

      Hi poj,

      Thanks for your suggestions and for showing 11 changes in my script. The script now works but in the result part, many unwanted combinations are found along with the desired 6-letter combinations. The 6-letter combinations are correct and this is only what I need in the result. How can I get only the desired 6-letter combinations in the result?

      Here goes the script again:

      #!/usr/bin/perl #1 add use strict use strict; use warnings; #2 add '' use File::Glob('bsd_glob'); ############################################ ## Output to a TEXT File using file handle: ############################################ my $output="Joint.txt"; open (my $fh,">",$output) or die"Cannot open file '$output'.\n"; #3 declare variables my (@array,@DNA,@list); my ($filename,$combi,$entry,$number,$DNA); do { print"\n\n Press 1 to Enter New File or 2 to Combine: "; $entry=<STDIN>; chomp $entry; if ($entry==1) { print"\n\n Enter New File Name (.txt): "; $filename = <STDIN>; chomp $filename; unless ( open(FILE, $filename) ) { print "Cannot open file \"$filename\"\n\n"; exit; } @DNA= <FILE>; close FILE; #5 add chomp chomp(@DNA); #6 add join by comma $DNA = join(',',@DNA); push @array, $DNA; #7 not needed array1=array; } elsif ($entry==2) { # Curly brace for entry2 starts $number=@array; print"\n\n No. of Elements in Joined Array: $number\n"; print $fh "\n\n No. of Elements in Joined Array: $number\n"; + # To produce all possible combinations of different elements: #10 use simple $_ on @array $combi = join('',map {'{'.$_.'}'} @array); @list = bsd_glob($combi); print"\n Results:\n"; print $fh "\n Results:\n"; #11 print each element on new line print join "\n",@list; print $fh join "\n",@list; } # Curly brace for Entry 2 ends: } until ($entry==2); # Square bracket for do-until: close $output; exit;

      Here goes the result of cmd and of output file Joint.txt:

      No. of Elements in Joined Array: 3 Results: A1T1C1G1A1C1 # This is correct A1T1C1G1 A1T1C1G1 A1T1C1G1 A1T1C1G1 A1T1C1G1 A1T1C1G1 A1T1C1G1 A1T1C1G2A1C1 # This is correct A1T1C1G2 A1T1C1G2 A1T1C1G2 A1T1C1G2 A1T1C1G2 A1T1C1G2 A1T1C1G2 A1T1C2G1A1C1 # This is correct A1T1C2G1 A1T1C2G1 A1T1C2G1 A1T1C2G1 A1T1C2G1 A1T1C2G1 A1T1C2G1 A1T1A1C1 A1T1 A1T1 A1T1 A1T1 A1T1 A1T1 A1T1 A1T1A1C1 A1T1 A1T1 A1T1 A1T1 A1T1 A1T1 A1T1 A1T1A1C1 A1T1 A1T1 A1T1 A1T1 A1T1 A1T1 A1T1 A1T1A1C1 A1T1 A1T1 A1T1 A1T1 A1T1 A1T1 A1T1 A1T1A1C1 A1T1 A1T1 A1T1 A1T1 A1T1 A1T1 A1T1 A1T1A1C1 A1T1 A1T1 A1T1 A1T1 A1T1 A1T1 A1T1 A2T3C1G1A1C1 # This is correct A2T3C1G1 A2T3C1G1 A2T3C1G1 A2T3C1G1 A2T3C1G1 A2T3C1G1 A2T3C1G1 A2T3C1G2A1C1 # This is correct A2T3C1G2 A2T3C1G2 A2T3C1G2 A2T3C1G2 A2T3C1G2 A2T3C1G2 A2T3C1G2 A2T3C2G1A1C1 # This is correct A2T3C2G1 A2T3C2G1 A2T3C2G1 A2T3C2G1 A2T3C2G1 A2T3C2G1 A2T3C2G1 A2T3A1C1 A2T3 A2T3 A2T3 A2T3 A2T3 A2T3 A2T3 A2T3A1C1 A2T3 A2T3 A2T3 A2T3 A2T3 A2T3 A2T3 A2T3A1C1 A2T3 A2T3 A2T3 A2T3 A2T3 A2T3 A2T3 A2T3A1C1 A2T3 A2T3 A2T3 A2T3 A2T3 A2T3 A2T3 A2T3A1C1 A2T3 A2T3 A2T3 A2T3 A2T3 A2T3 A2T3 A2T3A1C1 A2T3 A2T3 A2T3 A2T3 A2T3 A2T3 A2T3 C1G1A1C1 C1G1 C1G1 C1G1 C1G1 C1G1 C1G1 C1G1 C1G2A1C1 C1G2 C1G2 C1G2 C1G2 C1G2 C1G2 C1G2 C2G1A1C1 C2G1 C2G1 C2G1 C2G1 C2G1 C2G1 C2G1 A1C1 A1C1 A1C1 A1C1 A1C1 A1C1 C1G1A1C1 C1G1 C1G1 C1G1 C1G1 C1G1 C1G1 C1G1 C1G2A1C1 C1G2 C1G2 C1G2 C1G2 C1G2 C1G2 C1G2 C2G1A1C1 C2G1 C2G1 C2G1 C2G1 C2G1 C2G1 C2G1 A1C1 A1C1 A1C1 A1C1 A1C1 A1C1 C1G1A1C1 C1G1 C1G1 C1G1 C1G1 C1G1 C1G1 C1G1 C1G2A1C1 C1G2 C1G2 C1G2 C1G2 C1G2 C1G2 C1G2 C2G1A1C1 C2G1 C2G1 C2G1 C2G1 C2G1 C2G1 C2G1 A1C1 A1C1 A1C1 A1C1 A1C1 A1C1 C1G1A1C1 C1G1 C1G1 C1G1 C1G1 C1G1 C1G1 C1G1 C1G2A1C1 C1G2 C1G2 C1G2 C1G2 C1G2 C1G2 C1G2 C2G1A1C1 C2G1 C2G1 C2G1 C2G1 C2G1 C2G1 C2G1 A1C1 A1C1 A1C1 A1C1 A1C1 A1C1 C1G1A1C1 C1G1 C1G1 C1G1 C1G1 C1G1 C1G1 C1G1 C1G2A1C1 C1G2 C1G2 C1G2 C1G2 C1G2 C1G2 C1G2 C2G1A1C1 C2G1 C2G1 C2G1 C2G1 C2G1 C2G1 C2G1 A1C1 A1C1 A1C1 A1C1 A1C1 A1C1 C1G1A1C1 C1G1 C1G1 C1G1 C1G1 C1G1 C1G1 C1G1 C1G2A1C1 C1G2 C1G2 C1G2 C1G2 C1G2 C1G2 C1G2 C2G1A1C1 C2G1 C2G1 C2G1 C2G1 C2G1 C2G1 C2G1 A1C1 A1C1 A1C1 A1C1 A1C1 A1C1 C1G1A1C1 C1G1 C1G1 C1G1 C1G1 C1G1 C1G1 C1G1 C1G2A1C1 C1G2 C1G2 C1G2 C1G2 C1G2 C1G2 C1G2 C2G1A1C1 C2G1 C2G1 C2G1 C2G1 C2G1 C2G1 C2G1 A1C1 A1C1 A1C1 A1C1 A1C1 A1C1 C1G1A1C1 C1G1 C1G1 C1G1 C1G1 C1G1 C1G1 C1G1 C1G2A1C1 C1G2 C1G2 C1G2 C1G2 C1G2 C1G2 C1G2 C2G1A1C1 C2G1 C2G1 C2G1 C2G1 C2G1 C2G1 C2G1 A1C1 A1C1 A1C1 A1C1 A1C1 A1C1
        That looks like you have some blank lines in the data files probably at the end. If you print $DNA you should see commas with no values between them. Either edit the files or add a filter like this ;
        $DNA = join(',',grep(/[ACGT]\d[ACGT]\d/,@DNA)); print "$DNA\n";
        poj
Re^5: How can one get all possible combinations of elements of different arrays using File::Glob(bsd_glob)?
by hdb (Monsignor) on Apr 24, 2013 at 21:15 UTC

    The key is in the glob function. If you feed it a string like "{1,2}{a,b,c}" it creates all combinations of elements within the braces. Here is a complete solution for your problem. I hope you can adapt it to your needs. There is nothing really new in there.

    use strict; use warnings; use File::Glob qw{bsd_glob}; my $string; my $entry; do { print"\n\n Press 1 to Enter New File or 2 to Combine: "; $entry=<STDIN>; chomp $entry; if ($entry==1) { print"\n\n Enter New File Name (.txt): "; my $filename = <STDIN>; chomp $filename; open my $fh, "<", $filename or die "Cannot open $filename.\n"; my $DNA; { local $/=undef; $DNA = <$fh>; } close $fh; chomp $DNA; $DNA=~s/\n/,/g; $string .= "{$DNA}"; } # Curly brace for entry1 ends: } until ($entry==2); for (bsd_glob $string) { print "~$_~\n"; }

    So for every file you input, it creates this substring "{...,...,...}" with all elements from the file and adds it to the previous substrings of the same kind. When you are done, the overall string is fed into glob to create all combinations. I hope this makes it clear.

      Hi hdb,

      Thank you for the code. It works but the problem is that it produces all the combinations alongwith the desired 6-letter combinations i.e.

      ~A1T1C1G1A1C1~ ~A1T1C1G2A1C1~ ~A1T1C2G1A1C1~ ~A2T3C1G1A1C1~ ~A2T3C1G2A1C1~ ~A2T3C2G1A1C1~

      Here is the text output of your code:

      ~A1T1C1G1A1C1~ ~A1T1C1G1~ ~A1T1C1G1~ ~A1T1C1G1~ ~A1T1C1G1~ ~A1T1C1G1~ ~A1T1C1G1~ ~A1T1C1G1~ ~A1T1C1G2A1C1~ ~A1T1C1G2~ ~A1T1C1G2~ ~A1T1C1G2~ ~A1T1C1G2~ ~A1T1C1G2~ ~A1T1C1G2~ ~A1T1C1G2~ ~A1T1C2G1A1C1~ ~A1T1C2G1~ ~A1T1C2G1~ ~A1T1C2G1~ ~A1T1C2G1~ ~A1T1C2G1~ ~A1T1C2G1~ ~A1T1C2G1~ ~A1T1A1C1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1A1C1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1A1C1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1A1C1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1A1C1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1A1C1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A1T1~ ~A2T3C1G1A1C1~ ~A2T3C1G1~ ~A2T3C1G1~ ~A2T3C1G1~ ~A2T3C1G1~ ~A2T3C1G1~ ~A2T3C1G1~ ~A2T3C1G1~ ~A2T3C1G2A1C1~ ~A2T3C1G2~ ~A2T3C1G2~ ~A2T3C1G2~ ~A2T3C1G2~ ~A2T3C1G2~ ~A2T3C1G2~ ~A2T3C1G2~ ~A2T3C2G1A1C1~ ~A2T3C2G1~ ~A2T3C2G1~ ~A2T3C2G1~ ~A2T3C2G1~ ~A2T3C2G1~ ~A2T3C2G1~ ~A2T3C2G1~ ~A2T3A1C1~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3A1C1~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3A1C1~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3A1C1~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3A1C1~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3A1C1~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3~ ~A2T3~ ~C1G1A1C1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G2A1C1~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C2G1A1C1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~C1G1A1C1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G2A1C1~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C2G1A1C1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~C1G1A1C1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G2A1C1~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C2G1A1C1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~C1G1A1C1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G2A1C1~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C2G1A1C1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~C1G1A1C1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G2A1C1~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C2G1A1C1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~C1G1A1C1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G2A1C1~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C2G1A1C1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~C1G1A1C1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G2A1C1~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C2G1A1C1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~C1G1A1C1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G1~ ~C1G2A1C1~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C1G2~ ~C2G1A1C1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~C2G1~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~A1C1~ ~~ ~~ ~~ ~~ ~~ ~~ ~~

      Here the input files i.e. k1.txt, k2.txt, k3.txt are small. When the input files are large, then I shall face problem in selecting the desired longest combinations from a very large cmd or text file output. It will be much easier if the output text file shows only the longest combinations as given above. I think it is not very easy task in perl. I think so because poj has also suggested a script which produces many unwanted combinations along with the desired 6-letter longest combinations. From the output text file, the unwanted combinations are to be deleted manually to retain only the longest correct, desired combinations. It will be a very time-taking task for more input files with large size. I wish perl could solve this problem.

        Not what I get. I only get the six desired lines. Probabaly your k?.txt files have a lot of empty lines??? In which case, you need to modify the code by adding two more lines:

        chomp $DNA; $DNA=~s/\n/,/g; $DNA=~s/,+$//g; # new $DNA=~s/,,+/,/g; # new $string .= "{$DNA}";

        This removes multiple commata or trailing commata created by empty lines. Let me know whether this solves the problem.