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

I am having a hard time understanding the logic behind the loop required to parse a file that contains many batches that correlate only with their detail files. To the best of my ability, I have tried to give an example of this issue. The example is as follows:

Each document will consist of the same layout. The first line of the file is the file header (FH) and it contains information regarding the contents of the file. Throughout the document, we will have numerous batch headers (BH). Information contained within the BH is only pertinent to the subsequent 0006 (detail records). There is a correlation between the BH and it's respective 0006 (detail records) The file trailer is indicated by the FT. This contains the record count. For example, I will have to take information from the BH segment and perform regular expressions based upon the content in the detail lines located immediately below the BH. Therefore, the information contained in the BH must be used for the RegExp in the subsequent detail lines. Once all of the detail lines have been read in a specific BH, the process will start over by taking the values from the next BH. The process will be completed once the entire file has been read.

Example File
FH825693963
BH0001000123
0006125 (Translate from BH0001000123)
0006285 (Translate from BH0001000123)
0006387 (Translate from BH0001000123)
0006496 (Translate from BH0001000123)
0006311 (Translate from BH0001000123)
0006423 (Translate from BH0001000123)
BH0001000456
0006585 (Translate from BH0001000456)
0006658 (Translate from BH0001000456)
0006798 (Translate from BH0001000456)
BH0001000789
0006996 (Translate from BH0001000789)
0006587 (Translate from BH0001000789)
FT0000000016

FH: File Header, BH: Batch Header, FT: File Trailer.

I truly appreciate all help that has been given to me in the past. Many thanks in advance for any and all advice.

Lastly, I would like to thank fsn, Bird, dug, anithri, Aristotle, and bronto for their help on my last question. I decided to post another thread because I felt that I did not describe my problem properly.

Thanks again!!!

  • Comment on Parse File Containing Multiple Batches With Correlating Detail Records

Replies are listed 'Best First'.
Re: Parse File Containing Multiple Batches With Correlating Detail Records
by alien_life_form (Pilgrim) on Sep 18, 2002 at 07:40 UTC
    Greetings,

    what about:

    while(<>) { chomp; if(/^FT.*/) { $ft_flag ++; next; } if(/^FH.*/) { $fh_flag ++; next; } if($ft_flag) {...; next;} if($fh_flag) {...; next;} if(/^BH.*/) { $current_bh=$_; next; } if(^0006.*) { do_whatever_using($current_bh,$_); next; } }

    Cheers,
    alf
    You can't have everything: where would you put it?
Re: Parse File Containing Multiple Batches With Correlating Detail Records
by anithri (Beadle) on Sep 18, 2002 at 18:28 UTC
    @lines = <>; #Slurp the whole thing. $fh = shift @lines; #First line of whole is FH line $ft = pop @lines; #Last line of while if FT line chomp ($fh,$ft); #get rid of newlines @segments = split /^BH/, join "",@lines; #split it up based on a BH at + beginning of line; shift @segments; #First segment will be empty. foreach $segment (@segments) { #loop through segments $segment = "BH".$segment; #replace missing BH at beginning that wa +s removed by split @lines = split /\n/,$segment; #split the segment on new lines chomp @lines; #get rid of newlines $batchhead = shift @lines; #first row is the Batch header foreach $trans (@lines) { #Loop through remaining process($trans, $batchhead); #process individual lines } }
Re: Parse File Containing Multiple Batches With Correlating Detail Records
by anithri (Beadle) on Sep 18, 2002 at 18:39 UTC
    $fh = <>; #first line of input is FT chomp $fh; #get rid of newlines $/ = "\nBH"; #set Input record seperator to newline followed by BH while (<>) { #loop through each chunk @lines = split /\n/,$_; #split chunk into lines chomp @lines; #get rid of newlines; $bh = shift @lines; #BH is first line. $ft = pop @lines; #on last iteration FT will be last line, otherwi +se the lastline is a bare BH ($bh =~ /^BH/) || ($bh .= "BH" . $bh"); #if $bh doesn't start wit +h BH then put it back. foreach $trans (@lines) { process($trans, $bh); #each remaining line is a single transac +tion line } }
Re: Parse File Containing Multiple Batches With Correlating Detail Records
by csotzing (Sexton) on Sep 18, 2002 at 10:41 UTC
    Or...

    my $fh = new FileHandle($fileName,">"); if (! defined $fh) { print STDERR "Error reading $fileName\n"; exit(2); } my ($bh,$fh,$ft); while (my $line = <$fh>) { chomp($line); if ($line =~ /^BH/) { $bh = $line; } elsif ($line =~ /^(F[HT])/) { eval("\$" . lc($1) . " = $line"); next; } elsif (defined $bh) { callSub($line,$bh); } } close($fh);

    print(map(lc(chr),split(6,qw/99672682673683684689632658645641610607/)));