use strict; use warnings; use MCE::Loop; use MCE::Candy; ## Input and output files defined here as well as what we are searching for in the input file my $input_file = shift || 'InputFile.OH1'; my $output_file = shift || 'OutputFile.csv'; my $match_string = "+ "; open my $ofh, ">", $output_file or die "cannot open '$output_file' for writing: $!\n"; ## This writes a header row that GIS sees as the column heading print $ofh "HEC1_ID,Q100_Base,TTP,Area\n"; MCE::Loop::init { use_slurpio => 1, chunk_size => 1, max_workers => 4, gather => MCE::Candy::out_iter_fh($ofh), RS => "\n${match_string}", }; ## Below, each worker receives one record at a time ## Output order is preserved via MCE::Candy::out_iter_fh ## EXAMPLE INPUT FILE Line 1##+ BPI30 1319. 13.50 477. 147. 49. 4.64 Line 2## Line 3## ROUTED TO Line 4##+ RPI30 1220. 13.75 475. 147. 49. 4.64 Line 5## Line 6## HYDROGRAPH AT Line 7##+ BPI31 765. 12.42 102. 26. 9. .73 Line 8## Line 9## 2 COMBINED AT Line 10##+ CPI31 1242. 13.75 571. 172. 58. 5.37 mce_loop_f { my ( $mce, $chunk_ref, $chunk_id ) = @_; ## Skip initial record containing header lines including *** *** if ( $chunk_id == 1 && $$chunk_ref !~ /^${match_string}/ ) { ## Gathering here is necessary when preserving output order, ## to let the manager process know chunk_id 1 has completed. MCE->gather( $chunk_id, "" ); MCE->next; } ## Each record begins with "+ " my ( $k1, $k2, $k3, $k4 ) = ( "", "", "", "" ); open my $ifh, "<", $chunk_ref; while ( <$ifh> ) { $k1 = $1 and next if $. == 1 && /^\S\s+(\S+)/; $k2 = $1 and next if $. == 1 && /^\S\s+\S+\s+(\S+)/; $k3 = $1 and next if $. == 1 && /^\S\s+\S+\s+\S+\s+(\S+)/; $k4 = $1 and last if $. == 1 && /(\S+)\s*$/; } close $ifh; ## Gather values. ## This outputs everything to the output file in the format below. MCE->gather( $chunk_id, "$k1,$k2,$k3,$k4\n" ); } $input_file;