use warnings; use strict; use diagnostics; my %bills; my $currBill = 'void'; my $type = 'header'; $datafile = "datafile.txt"; open(DATA, $datafile) || die ("Cannot open $datafile: $!"); while () { chomp; if ($_ =~ /^101010000/) { $currBill = $1; $type = 'header'; } elsif ($_ =~ /^301033000/) { $currBill = $1; $type = 'data'; } else { push @{$bills{$currBill}{$type}}, $_; } } close(DATA); open($outputdata, '>', 'outputfile.txt' || die "Cannot open output file output.txt: $!"); for my $bill (sort keys %bills) { print $outputdata ">>>> $bill\n"; print $outputdata "Header\n" . (join "\n", @{$bills{$bill}{'header'}}) . "\n" if exists $bills{$bill}{'header'}; print $outputdata "Data\n" . (join "\n", @{$bills{$bill}{'data'}}) . "\n" if exists $bills{$bill}{'data'}; }