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

viktor has asked for the wisdom of the Perl Monks concerning the following question:

Dear monks , I have written a script which selects the data till the line matches ======== then take that data in an array and execute a system command. The command has a default ouputfile in which the analysis is done and written. But my script overwrites the earlier data. Means the code is correct only thing is that I am overwriting the data in the ouput file which is being generated by the software which I am using by system command . How I can avoid that .

#!/usr/bin/perl -w use strict; my @aln; open(FILE,"vik.fna"); while (my $line = <FILE>) { if ($line !~ /^==========/) { push (@aln, $line); } else { open (SEQFILE, ">vik.tmp"); print SEQFILE join("",@aln); close SEQFILE; @aln = (); system("java -jar BMGE.jar -i vik.tmp -t AA -o tmsa.out") +; } }

Replies are listed 'Best First'.
Re: using the system command
by AnomalousMonk (Archbishop) on Jul 01, 2011 at 12:11 UTC
    How I can avoid that .

    Open the file in  >> append mode:

    c:\@Work\Perl\junque>perl -wMstrict -e "my $file = 'junk'; for my $s (qw(foo bar baz)) { open my $fh, '>>', $file or die qq{opening '$file': $!}; print $fh qq{this is $s \n} or die qq{writing '$file': $!}; close $fh or die qq{closing '$file': $!}; } " c:\@Work\Perl\junque>cat junk this is foo this is bar this is baz
Re: using the system command
by moritz (Cardinal) on Jul 01, 2011 at 10:55 UTC
    But my script overwrites the earlier data.

    Well, then don't do it. Chose a different name for the output file each time you run the system command.

      thanks but i I have to do that same thing 1000 times as the array is catching some of my intended data and it is a long file so i cannot generate hundreds of files .Is that its the fault of the software as I cannot automate it .

        viktor:

        If you're on a unix box, then you can glue files together like this:

        generatefile foo cat foo >>the_big_file generatefile foo cat foo >>the_big_file

        So you can use the same trick in your script. If you're on DOS, there's a similar trick using copy, but you'll have to read the help page on it, as I don't recall it well.

        ...roboticus

        When your only tool is a hammer, all problems look like your thumb.

        So you neither want to override the files, nor do you want to preserve them. What do you want?

        and it is a long file so i cannot generate hundreds of files

        Uhm, why not? A decent computer can handle hundreds of long files, whatever that means.

        If disc space is an issue, you could compress the files after they are generated. Or extract the information you want from them, and then delete them.

Re: using the system command
by Anonymous Monk on Jul 01, 2011 at 10:57 UTC

    How I can avoid that .

    stop overwriting the file :) use a different filename each time, like

    use POSIX; my $procdate = POSIX::strftime('%Y-%m-%d-%H-%M-%S', localtime); my $tmsa = "tmsa.out-$procdate"; system .... $tmsa
Re: using the system command
by rev_1318 (Chaplain) on Jul 01, 2011 at 15:13 UTC

    As others already pointed out, there's no reason to use hundreds of files, you can easily concatenate them, either on the fly or afterwards... So use a sequence number, time stamp or whatever you like.

    I would like to make a few general observations about your code:

    • use the 3-argument form of open
    • check the result of open
    • use lexical file handles
    • so, in stead if e.g. open (SEQFILE, ">vik.tmp"), use
      open my $seqfile, '>', "vik.tmp" or die "cannot open vik.tmp: $!\n";

    • also, check the result of close!
    • close $seqfile or die "cannot close vik.tmp: $!\n";

    • no need to join your line before print
    • print $seqfile @aln is enough

    Paul