Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Run a perl code on all input files and have the results in different output files

by SaraMirabi (Novice)
on May 12, 2020 at 07:48 UTC ( [id://11116697]=perlquestion: print w/replies, xml ) Need Help??

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

Hi guys,

I am decoding my TAPs with Tap3edit. I introduce my input file in the Perl code and have the decoded file as an output. Now I have about 200 files I want my Perl code decode them automatically and save them as different outputs with the same name in XML. I found glob and basename for finding my specific file names in which their name starts with DA and then start to decode but in the result, it seems only the first file has been decoded. I really appreciate it if anyone can help me. I apologize if it too basic, cause I am so new with Perl.

#!/usr/bin/perl -w use strict; use warnings; use Data::Dumper; use XML::Dumper; use TAP3::Tap3edit; $Data::Dumper::Indent=1; $Data::Dumper::Useqq=1; my $dump = new XML::Dumper; use File::Basename; my $perl=''; my $xml=''; my $tap3 = TAP3::Tap3edit->new(); foreach my $file(glob 'Taps/X*') { $files= basename($file); $tap3->decode($files) || die $tap3->error; } my $filename="Out.xml"; $perl = $tap3->structure; $dump->pl2xml($perl, $filename); print "Done \n";
  • Comment on Run a perl code on all input files and have the results in different output files
  • Download Code

Replies are listed 'Best First'.
Re: Run a perl code on all input files and have the results in different output files
by bliako (Monsignor) on May 12, 2020 at 08:54 UTC

    As a quick remedy until someone who knows better can help you, try opening the output file before the loop, and then APPEND the structure to the file inside the loop. I believe from a quick glance at XML::Dumper that pl2xml($perl, $filename) does not append but overwrites whatever the current contents of file with $perl. If you omit the $filename, you will get the xml string back, e.g. my $xmlstr = pl2xml($perl); (untested). So, open the output file before the loop: open($fh, '>:encoding(UTF-8)', $filename) or die "file, $!"; Then inside the loop, after decode(): $perl = $tap3->structure; my $xmlstr = $dump->pl2xml($perl); print $fh $xmlstr; OR simpler: print $fh $dump->pl2xml($tap3->structure); And after the loop close $fh; But perhaps you want a new $tap3 object to be created inside the loop each iteration?

      Is it possible to share the edited code with me,I didn't get unfortunately. yes, I need tap3. This code perfectly goes fine for one file, I just want to give a batch of similar code and input and get the outputs.
        my $filename="Taps/Output.xml"; my $fh; open($fh, '>:encoding(UTF-8)', $filename) or die "file, $!"; foreach my $file(glob 'Taps/DA*') { my $tap3 = TAP3::Tap3edit->new(); $files= basename($file); #<< are you sure this is needed/does it wo +rk? $tap3->decode($files) || die $tap3->error; print $fh $dump->pl2xml($tap3->structure); } close $fh;

        WARNING: This code reads just ONE tap file, decodes it and dumps it. It does that for all TAP files. Separately. I am not sure you will get correct output, because I am not sure you want to read and decode all files first or decode and dump each separately, as above code does.

Re: Run a perl code on all input files and have the results in different output files
by Anonymous Monk on May 12, 2020 at 13:17 UTC

    What you really need is someone with experience of the specific Perl modules, which I do not have.

    I did read the source of Tap3::Tap3edit though, and it looks to me like the decode() method replaces whatever was there before.

    Of course, this means that at the end of the loop it would be the last file left in the $tap3 object, not the first. So something else must also be going on.

    I also reiterate a previous poster's question of the use of basename(). As your code is written, the glob() finds all files named X* in directory Taps/ under your current directory. But by feeding decode() the basename of the file you find you are actually attempting to read a file in your current directory, not in Taps/. Now, you are checking the status of the operation, and though in general your check is subtly wrong (your habit should be to use ... or die ... rather than ... || die ...), in this specific case I do not think that the tighter binding of || versus or invalidates the test.

    Given all this, I believe that if I were in your position I would dump the contents of $file, $files, and any relevant information about the parse immediately after the call to decode() and see if it was what I expected. Maybe initially put die 'Debugging'; after the dump so that you are only dealing with one mass of information at a time, instead of a whole directories' worth.

    Irrelevantly to your question, I would like to note that for a self-confessed newbie you are doing basic things right. Using use strict; and use warnings; will spare you grief now and in the future.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11116697]
Approved by Discipulus
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (4)
As of 2024-04-19 03:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found