Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic

writing array element to a file

by francesca1987 (Initiate)
on Apr 25, 2013 at 09:19 UTC ( #1030631=perlquestion: print w/replies, xml ) Need Help??
francesca1987 has asked for the wisdom of the Perl Monks concerning the following question:

Hello! I'm new in perl but I need to write each element of an array into a file (appending). The array elements are the lines of another file starting with >. I wrote the following:
open in, "rep_set_ass_tax.fna"; while ($line=<in>) { if($line=~/>/) { @vettore=split(/\s+/, $line); open my $fh, ">>seq_id.txt" or die "Cannot open output.txt: $!"; foreach (@vettore); print $_ . "\n"; close my $fh; } }
I have the following errors:
MacQIIME Mac-Pro-di-Francesca:cartella senza titolo $ perl syntax error at line 6, near ");" syntax error at line 8, near "$fh;"
Who can help me?

Replies are listed 'Best First'.
Re: writing array element to a file
by hdb (Monsignor) on Apr 25, 2013 at 09:42 UTC

    At a first glance, it seems you need a pair of braces around the print statement. And the file handle in the print statement.

    while ($line=<in>) { if($line=~/>/) { @vettore=split(/\s+/, $line); open my $fh, ">>seq_id.txt" or die "Cannot open output +.txt: $!"; foreach (@vettore) { # { was missing here, removed ; print $fh $_ . "\n"; # file handle was missing } # } was missing here close $fh; # removed my } }

    UPDATE: The regex for > at the beginning of line is /^>/. The name of the file you are trying to open for writing is inconsistent with the error message.

Re: writing array element to a file
by Random_Walk (Prior) on Apr 25, 2013 at 09:46 UTC

    Welcome to Perl Monks.

    The syntax problem with your code is that foreach runs a loop so you need to use it like this:

    foreach (@vettore) { print $_ . "\n"; }

    But it looks like you may actually want to print the output to your filehandle $fh by replacing your print with print $fh "$_\n"

    Perhaps this script will help show some other ideas

    # The following two lines check your code and # alert you to many common errors use strict; use warnings; # Lets keep the filespec out the main code # using my when defining a variable limits its scope. my $infile = "rep_set_ass_tax.fna"; my $outfile = "seq_id.txt"; # No point going on if we can not open both files # You were opening the outfile in a loop before, lots of opens # and closes happening that were not needed open my $in, '<', $infile or die "Can't read $infile: $!\n"; open my $out, '>>', $outfile or die "Can't read $outfile: $!\n"; while (my $line=<$in>) { if($line=~/^>/) { # ^ added for only lines starting with +> my @vettore=split(/\s+/, $line); foreach (@vettore) { # can use for(@array) but they are the s +ame print $out "$_ \n"; # Variables can be interpolated in a stri +ng } # end foreach loop } } close $in; close $out;

    If you are going to post more often it may be worth having a look at how to format your posts :)


    Pereant, qui ante nos nostra dixerunt!
      Hi! Thanks everyone for the help, I know I did a lot of stupid errors, but I just started with perl. I tried to run the script you suggested me, but it wasn't exactly what I need to do. I need to copy in the stdout only the number after the >, without the following lines. These are few lines of my input file:
      I want to copy only the numers.... Running the sipt you suggested, I obtained this:
      How can I modify it? Man thanks for your help!! Francesca

        So you have a series of lines that look something like this

        > 22 GATTGATGCC... > 2 GATGGATGTG... > 26 GATGCATGAT... > 52 GATGATGTGG...

        And in your output file you just want the numbers.

        The split we had in the original code splits each line on spaces into the @vettore array. If we only want to print the second element of this array (the number) then we do not need the foreach loop. We can alter our print to directly address the second element of the arrayprint $out "$vettore[1]\n"; (array indexing starts at 0). Here is our new line processing block:

        while (my $line=<$in>) { if($line=~/^>/) { my @vettore=split(/\s+/, $line); print $out "$vettore[1]\n"; } }

        For fun it can also be done as a one liner. Here I added a bit more checking of the line to ensure it had some GATC characters following the number

        perl -nle "if (/^>\s+(\d+)\s+[GATC]+/) {print $1}" rep_set_ass_tax.fna >> seq_id.txt

        If you are not on windows you may need to change the two " quotes to ' quotes.


        Pereant, qui ante nos nostra dixerunt!
Re: writing array element to a file
by baxy77bax (Deacon) on Apr 25, 2013 at 09:58 UTC
    you should really put your code in <code></code> tags. But from what I can see your code looks like this(more or less):
    open in, "rep_set_ass_tax.fna"; while ($line=<in>) { if($line=~/>/) { @vettore=split(/\s+/, $line); open my $fh, ">>seq_id.txt" or die "Cannot open output.txt: $!"; # + There is no need to open a file each time you need to print somethin +g into it if it is the same file. just open it once before the loop a +nd print to it foreach (@vettore); # What is a loop and what is a proper way to w +rite one. So you started a loop and what are you going to do with it( +I mean variables in the loop) print $_ . "\n"; # OK, so you want to print something, but where + to STDOUT or into a file that you have opened close my $fh; # again my doesn't have any effect if use strict is +not called. } }
    First of all try to use strict and warnings, you will get a lot of info about your errors. Second, you have a some syntax errors(see comments in the above code). I I were you I would do something like this
    use strict; use warnings; open(IN, "<", "rep_set_ass_tax.fna") or die "Died!!"; open (OUT , ">","seq_id.txt") or die "Cannot open output.txt: $!"; while (my $line=<IN>) { if($line=~/>/) { my @vettore=split(" ", $line); foreach (@vettore){ print OUT $_ . "\n"; } } } close IN; close OUT;
    now this maybe is not exactly what you need to do but it will get you started



    use strict; use warnings; open(IN, "<", "rep_set_ass_tax.fna") or die "Died!!"; while (my $line=<IN>) { if($line=~/>(\d+)/) { print $1 . "\n"; } } close IN;
    UPDATE 2: Did you manage to get it working?? Also is this a fasta file orreally a one line file "> 1 ATTTAAA..."??? it is a bit strange if it is a one liner. usually those files look like this:
    >1 ATGT... >2 ATGGTGC..
    also is there a space between > and 1? so you did several things wrong down there: it should look like this:
    use strict; use warnings; my $infile = "rep_set_ass_tax.fna"; my $outfile = "seq_id.txt"; # you need to open this only if writing t +o a file open(IN, "<", $infile) or die "Died!!"; while (my $line=<IN>) { if($line=~/>\s*(\d+)/) { print $1 . "\n"; } } close IN;
    and use the code tags like:

    My code;


      Hi baxy! I did as you suggested in the update, the script run, but the output was empty! I run:
      use strict; use warnings; my $infile = "rep_set_ass_tax.fna"; my $outfile = "seq_id.txt"; open(IN, ">>", "rep_set_ass_tax.fna") or die "Died!!"; while (my $line=<IN>) { if($line=~/>(\d+)/) { print $1 . "\n"; } }
      What's the problem?
      close IN;
        This opens IN for output
        open(IN, ">>", "rep_set_ass_tax.fna") or die "Died!!";
        it should be
        open(IN, "<", "rep_set_ass_tax.fna") or die "Died!!";

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1030631]
Approved by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (4)
As of 2019-01-23 13:35 GMT
Find Nodes?
    Voting Booth?
    After Perl5, I'm mostly interested in:

    Results (403 votes). Check out past polls.