use warnings; use strict; my %bills; my $currBill = 'void'; my $type = 'header'; while () { chomp; if (/^1010100\.+(\d+)/) { $currBill = $1; $type = 'header'; } elsif (/^3010330\.+(\d+)/) { $currBill = $1; $type = 'data'; } else { push @{$bills{$currBill}{$type}}, $_; } } for my $bill (sort keys %bills) { print ">>>> $bill\n"; print "Header\n" . (join "\n", @{$bills{$bill}{'header'}}) . "\n" if exists $bills{$bill}{'header'}; print "Data\n" . (join "\n", @{$bills{$bill}{'data'}}) . "\n" if exists $bills{$bill}{'data'}; } __DATA__ 1010100.........123456..... #header line for bill # 123456 #some data #some data #some data #some data 1010100.........678910..... #header line for bill # 678910 #some data #some data #some data 3010330.........123456..... #bill detail for bill 123456 #some data #some data #some data #some data #some data 3010330.........678910..... #bill detail for bill 678910 data for 678910 #### >>>> 123456 Header #some data #some data #some data #some data Data #some data #some data #some data #some data #some data >>>> 678910 Header #some data #some data #some data Data data for 678910