Philip O'Brien
Philip O'Brien

Reputation: 4266

Working through multiple files one at a time in perl?

I have a perl script that opens a txt file, parses it so that the appropriate text is output to a csv file. I have working great now for one file, but I have loads of similar files to work through in the exact same way. I want to be able to just do this automatically so the code will work through file1.txt and parse the text I want to output.csv, then work through file2.txt and append this output to the same output.csv. I have included the relevan bits of my code below, excluding only the code that does the actual parsing within the while loop since I don't need to alter this. The input files are consistently named, e.g. file1.txt, file2.txt, file3.txt etc. and all reside in the same directory

my $mode = "none";
open(my $infile,"<","file1.txt") or die $!;
open (my $outfile,">>","output.csv") or die $!;
while (<$infile>)
{
    chomp; 
    if ($_ =~ /^Section 1/) {
        $mode = "sec1";
    }
    if ($_ =~ /^Section 2/) {
        $mode = "sec2";
    }

    if ($mode =~ "sec1") {
      $_=~ tr/,//d;

      if ($_ =~ /.\%$/){
        print $outfile $_;
        print $outfile "\n";
      }
      else{
        print $outfile $_;  
      }

    }    
}

close $infile;
close $outfile;

The output file should resemble this (not this text obviously, I'm just highlighting that it the output must be appended, which I think I have covered by using >> as opposed to >)

this is from file 1
this is from file 2
this is from file 3

Upvotes: 1

Views: 2567

Answers (4)

Borodin
Borodin

Reputation: 126772

Just put the necessary files into @ARGV as if they had been typed on the command line. Then read from the ARGV filehandle.

use strict;
use warnings;

our @ARGV = do {
    opendir my $dh, '.' or die $!;
    grep /^file\d+\.txt$/, readdir $dh;
};

while ( <ARGV> ) {
  ...
}

Upvotes: 1

TrueY
TrueY

Reputation: 7610

It is easy to open all files given in the command line. There is a special file handle, called ARGV.

Example:

#!/usr/bin/perl

use strict;
use warnings;

while (<ARGV>) {
    print $_;
}

Command line:

test.pl file*.txt

All files will be concatenated.

If you have the file list "inside" the code, you can load them to the @ARGV array, then use <ARGV>.

Upvotes: 0

Gilles Qu&#233;not
Gilles Qu&#233;not

Reputation: 185851

You can use the diamond operator <> and the scalar $ARGV variable :

use strict; use warnings;

while (<>) {
    print "Processing [$_] from $ARGV\n";
}

this is the same as

use strict; use warnings;

while (<ARGV>) {
    print "Processing [$_] from $ARGV\n";
}

if there's something in @ARGV.

Upvotes: 2

chrsblck
chrsblck

Reputation: 4088

You just need to wrap this in a loop like so:

for my $file ( @list_files ) {
    open $in_fh, "<", $file;
    while (my $line = <$in_fh>) {
    # and the rest of your stuff goes here

Upvotes: 3

Related Questions