Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Is it possible to insert a record after line 5 that appears on line 10?

by dirtdog (Monk)
on Jun 23, 2010 at 20:22 UTC ( [id://846166]=perlquestion: print w/replies, xml ) Need Help??

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

Oh ye Wise one's

I'm trying to figure out a way to loop thru a file looking for a record that begins with :35B: but only if it comes after(does not have to be immediately after) a :16R:SECMOVE record. Once found, i have to copy the :35B: record just under the above and nearest :17B: record which i've already passed.

#!/usr/bin/env perl use warnings; use strict; use Data::Dumper; my @B_Record; my $Rflag=0; my $Bflag=0; my $line; while (<DATA>) { if ( /^:17B:/) { print; $line = $.; print "35B to be copied after this line: $line\n"; next; } if ( (/^:16R::SECMOVE/) && ($Rflag == 0) ) { print; $Rflag = 1; next; } if ( ( /^:35B:/) && ($Rflag == 1) ) { print; splice(@B_Record); push @B_Record, $_; $Rflag = 0; $Bflag = 1; next; } if ( $Bflag == 1 ) { print; push @B_Record, $_; $Bflag = 0; next; } print; } __DATA__ :16S:LINK :16S:GENL :16R:USECU :35B:/GB/B5SDC53 UNICREDIT SP RIGHTS :16R:FIA :12C::CLAS//RXXXXX :16S:FIA :16R:ACCTINFO :97A::SAFE//NONREF :16S:ACCTINFO :16S:USECU :16R:CADETL :98A::RDTE//20100113 :16S:CADETL :16R:CAOPTN :13A::CAON//001 :22F::CAOP//EXER :17B::DFLT//N :98A::EXPI//20100129 :69A::PWAL//20100111/20100129 :16R:SECMOVE :22H::CRDB//CRED :35B:/GB/1234567 UNICREDIT SPA EUR0.50 :69A::TRDP//20100111/20100122 :90B::PRPP//ACTU/EUR1,589 :92D::NWRT//3,/20, :98B::PAYD//UKWN :16S:SECMOVE :70E::ADTX//PAYOUT METHOD TYPE CODE:SR NEW SHARE TYPE CODE:C TAXABLE CODE:N :16S:CAOPTN :16R:ADDINFO :70E::ADTX//CORP ACTION TYPE:SUBOFF

The above code is what i have so far...i just can't figure out how i'm going to print out a record after line 5 that I captured from line 10! hypothetically speaking

Any help would be mucho appreciated

Thanks

  • Comment on Is it possible to insert a record after line 5 that appears on line 10?
  • Download Code

Replies are listed 'Best First'.
Re: Is it possible to insert a record after line 5 that appears on line 10?
by Corion (Patriarch) on Jun 23, 2010 at 20:43 UTC

    You appear to be parsing SWIFT messages. The easiest way (as SWIFT messages are fairly short) would be to read the whole message into an array and then do array manipulation by iterating over the array indices and then inserting elements at the appropriate places. Of course you will need to find the right item after which to insert your new item, which will need some understanding of the sequence in which the items are allowed to appear, but I guess you have that already.

Re: Is it possible to insert a record after line 5 that appears on line 10?
by ikegami (Patriarch) on Jun 23, 2010 at 22:03 UTC
    my $seen_16r_secmove = 0; my $seen_17b = 0; my @buf; while (<>) { if (/^:17B:/) { $seen_17b = 1; print @buf; @buf = $_; } elsif ($seen_16r_secmove && $seen_17b && /^:35B:/) { print; } else { $seen_16r_secmove = 1 if /^:16R:SECMOVE$/; push @buf, $_; } } print @buf;

    Or a version that doesn't start buffering before it needs to:

    my $seen_16r_secmove = 0; my $seen_17b = 0; my @buf; while (<>) { if (/^:17B:/) { $seen_17b = 1; print @buf; @buf = $_; next; } $active = 1 if /^:16R:SECMOVE$/; if (!$seen_17b || $seen_16r_secmove && /^:35B:/) { print; } else { push @buf, $_; } } print @buf;

    Both handle all of these according to the given specs:

    :16R:SECMOVE :17B: :35B: :16R:SECMOVE :17B: :35B: :35B: :16R:SECMOVE :35B: :17B: :35B: :17B: :16R:SECMOVE :35B:

    Untested.

    Update: Simplified.

Re: Is it possible to insert a record after line 5 that appears on line 10?
by bichonfrise74 (Vicar) on Jun 23, 2010 at 20:41 UTC
    Here's something to help you get started. Notice in the first pass, I grabbed the 3rd record. And in the second pass, I printed the 2nd record.
    #!/usr/bin/perl use strict; my $data_pos = tell DATA; my $record; while (my $line = <DATA>) { chomp( $line ); $record = $line if ( $line =~ /^:16R:USECU/ ); } seek DATA, $data_pos, 0; while (my $line = <DATA>) { chomp( $line ); print "$line\n" if ( $record && $line =~/^:16S:GENL/ ); } __DATA__ :16S:LINK :16S:GENL :16R:USECU

      Thanks for all the advice and input! it looks like i will definitely have to loop thru the file twice.

Re: Is it possible to insert a record after line 5 that appears on line 10?
by AndyZaft (Hermit) on Jun 23, 2010 at 21:47 UTC
    Been at least 15 years since I worked in a bank, but because of it I always assume all data files can come in massive sizes, so based on that my solution would be something along the lines of ...

    Print everything till you hit :17B:, then you consider this the start of a record to watch for. Feed the lines that follow to an array till the first :35B: record, at which point you are ready to process this "block" between 17B and 35B. If there was a :16R:SECMOVE in between you print the first record of array, then the last, and then the rest, minus the last one, then go back to printing rows till you hit :17B: again. Of course spit out the array if there was no :16R:SECMOVE in there. Don't forget to empty the array before reuse.

    Obviously if :16R: can occur before :17B: and still need to process it that way, just modify accordingly. Guess it would help if I knew anything about these records and if they have any kinda order or whatnot. You could probably do this as an AWK oneliner too.

Re: Is it possible to insert a record after line 5 that appears on line 10?
by kejohm (Hermit) on Jun 23, 2010 at 23:02 UTC

    Building on what Corion said above, you might be interested in the Tie::File module. It allows you to access a file as a Perl array.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://846166]
Approved by toolic
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (4)
As of 2024-04-25 07:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found