Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

How to read a file containing filenames and pass as input to perl script?

by Kal87 (Novice)
on Apr 18, 2018 at 19:53 UTC ( [id://1213136]=perlquestion: print w/replies, xml ) Need Help??

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

Hi there, I'm using the below perl script to process an XML file where the filename is passed as an argument during runtime (Argv[0]) to the script. This works well, however, I would like to take this up a notch. I have another file (let's call it filename_list.txt) that contains a list of filenames (with absolute paths). Say the first two lines in that file read like this:
/home/kal/assemble.xml /home/tom/Venice.xml
I expect thousands of lines in filename_list.txt I'm looking to update the script so that it reads each line of filename_list.txt, and executes the twig and CSV bit for each file. Not sure how to get this going, could someone please help? I've attempted to use another bash script with a while, but it would be great if someone could suggest a faster method that involves just this perl script.
use Text::CSV_XS; use XML::Twig; my $csv = Text::CSV_XS->new({'sep_char' => "|",}, ); my $twig = XML::Twig->new( ); twig_handlers => {'EDI_DC40' => \&process_EDI_DC40,}, ); $twig->parsefile( $ARGV[0] ); sub process_EDI_DC40 { my( $twig, $thingy ) = @_; my @values = map { $thingy->first_child( $_ )->text } qw(DOCNUM MESTYP SNDPRN RCVPOR RCVPRN); $csv->say( *STDOUT, \@values ); + }

Replies are listed 'Best First'.
Re: How to read a file containing filenames and pass as input to perl script?
by choroba (Cardinal) on Apr 18, 2018 at 20:51 UTC
    Just open the file and read from it line by line by the diamond operator. Run your code on each filename. I'm not sure whether you can reuse the objects for the actual work you need to do, but if you can't, just create the objects inside the loop instead of outside.
    #!/usr/bin/perl use warnings; use strict; use Text::CSV_XS; use XML::Twig; my $twig = 'XML::Twig'->new(...); my $csv = 'Text::CSV_XS'->new(...); my $listfile = shift; open my $list, '<', $listfile or die $!; while (my $xmlfile = <$list>) { chomp $xmlfile; $twig->parsefile($xmlfile); ... }
    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
      @Choroba, Thanks, I tried the code as you suggested, but getting the error as
      Can't call method "text" on an undefined value at IDOCXML_parse2.pl li +ne 27, <$list> line 1. at IDOCXML_parse2.pl line 23 at IDOCXML_parse2.pl line 23
      Let me know what I'm missing. Thanks! The code is
      #!/usr/bin/perl use warnings; use strict; use Text::CSV_XS; use XML::Twig; my $listfile = shift; open my $list, '<', $listfile or die $!; while (my $xmlfile = <$list>) { chomp $xmlfile; my $twig = XML::Twig->new( twig_handlers => { 'EDI_DC40' => \&process_EDI_DC40, }, ); my $csv = Text::CSV_XS->new({ 'sep_char' => "|", }); $twig->parsefile($xmlfile); sub process_EDI_DC40 { my( $twig, $thingy ) = @_; my @values = map { $thingy->first_child( $_ )->text } qw(DOCNUM MESTYP SNDPRN RCVPOR RCVPRN); $csv->say( *STDOUT, \@values ); } }
        Somewhere in the data, there's an EDI_DC40 element that doesn't have all the child nodes. You need to check whether the child exists before calling a method on it:
        my @values = map { my $ch = $thingy->first_child( $_ ); $ch ? $ch->text : "" } qw( DOCNUM MESTYP SNDPRN RCVPOR RCVPRN );

        Also, as I mentioned, you probably don't need to create a new Twig and CSV objects for each file. Declaring the sub inside the loop makes no sense, either.

        #!/usr/bin/perl use warnings; use strict; use Text::CSV_XS; use XML::Twig; my $csv = 'Text::CSV_XS'->new({ sep_char => '|', }); sub process_EDI_DC40 { my ($twig, $thingy) = @_; my @values = map { my $ch = $thingy->first_child( $_ ); $ch ? $ch->text : "" } qw( DOCNUM MESTYP SNDPRN RCVPOR RCVPRN ); $csv->say(*STDOUT, \@values); } my $listfile = shift; open my $list, '<', $listfile or die $!; my $twig = 'XML::Twig'->new( twig_handlers => { EDI_DC40 => \&process_EDI_DC40, }, ); while (my $xmlfile = <$list>) { chomp $xmlfile; $twig->parsefile($xmlfile); }

        ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (5)
As of 2024-04-23 08:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found