Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

Read through directory and return matched data

by JonDepp (Novice)
on Nov 09, 2010 at 16:28 UTC ( #870335=perlquestion: print w/replies, xml ) Need Help??
JonDepp has asked for the wisdom of the Perl Monks concerning the following question:


I have a directory of text files and I am trying to write a script that opens the directory and then opens each subsequent file and reads each file line by line looking for a variable (acct_number) and if it finds that variable to output only the data pertaining to that variable. The text data looks like this:

NAME DOE, JOHN HIC XXXXXXXXXX ACNT XXXXXXXX + ICN XXXXXXXXXXXXX ASG Y MOA MA01 MA18 1234567891201 120109 22 001 72070 26 38.00 11.45 + 0.00 2.29 CO-45 26.55 9.16 + PR-2 2.29 PT RESP 2.29 CLAIM TOTALS 38.00 11.45 + 0.00 2.29 26.55 9.16 ADJ TO TOTALS: PREV PD INTEREST 0.00 LATE +FILING CHARGE 0.00 NET 9.16

I want to grab all the data between NAME and ADJ TO TOTALS if the acct_number variable matches the ACNT number of the data. There are many text files in the directory and they all are setup like this. The code I have below opens the directory and each file, but does not return any output even though I know the acct_number matches one within the data.

use strict; use warnings; my $dir = "V:/"; open OUTPUT, "> PEP/dirtest.txt" or die$!; print "What is acct number ?"; my $acct_number = <STDIN>; my @files; my @data; my @lines; my $file; my $flag1; my $flag2; opendir(BIN, $dir) or die "Can't open $dir: $!"; @files = map {$dir.'/'.$_} grep { $_ !~ /^\./ } readdir BI +N; { foreach $file (@files) { open FH, "$file"; while (<FH>) { $flag2 = 1 if $flag1 and /$acct_numbe +r/; $flag1 = 1 if /NAME/; push @lines, $_ if $flag1; if (/ADJ TO TOTALS:/) { print OUTPUT @lines if $flag2; $flag1=0; $flag2=0; @lines=(); } } } } closedir(BIN);

If anyone could tell me why I am not getting any output I would be most grateful!

Replies are listed 'Best First'.
Re: Read through directory and return matched data
by zentara (Archbishop) on Nov 09, 2010 at 16:37 UTC
    First break the problem into sections, first, are you getting any files? Can you print @files.

    Second, your path to files might need to be prepended with $dir, as you did in the readdir

    #{ open FH, "$file"; { open FH, "$dir/$file"; # instead, possibly?

    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh

      I can print @files, and I can also print the contents of each file.

      I tried to put in the full path $dir/$file, but it gives me a readline on closed filehandle error.

Re: Read through directory and return matched data
by sundialsvc4 (Abbot) on Nov 09, 2010 at 18:58 UTC

    Would this happen to be (ick...) Microsoft Windows?   ;-)

    If so, then not only should you use File::Find, but you should also cache all of the filenames found, into an array, first.   Then, go back and “run the list” of filenames that you just found.

    The file-scanning primitives in Windows are easily flummoxed by any sort of file-operation that occurs in the meantime.   Therefore, “search first, ask questions later.”

Re: Read through directory and return matched data
by umasuresh (Hermit) on Nov 09, 2010 at 16:42 UTC
Re: Read through directory and return matched data
by Cristoforo (Curate) on Nov 10, 2010 at 01:22 UTC
    my $acct_number = <STDIN>;

    It is not matching because you haven't chomped $acct_number to remove the newline.

    chomp(my $acct_number = <STDIN>);

    Update: It appears that 'NAME' and $acct_number are on the same line (in your sample data). So when you set $flag1, you should test for '$acct_number' on the same input line. Then you would have a matching record (in addition to removing the newline from $acct_number. :-)

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://870335]
Approved by ww
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (9)
As of 2017-11-23 09:53 GMT
Find Nodes?
    Voting Booth?
    In order to be able to say "I know Perl", you must have:

    Results (333 votes). Check out past polls.