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

Hi monks, I need some help with this one as im not sure how to go about it without severely changing my code.

use strict; # the connectors in the the ping connectivity my @fromConnectors; my @toConnectors; # The ping connectivity char my @fromPing; my @toPing; # reads each line until 'General manual list' is found do { $_ = <> } until /General manual list/; <> for (1..3); # skips 3 lines from title # read input file while (<>) { last if /^\+/; # split table by pipelines assigning columns to each my ($misc1, $misc2, $from, $to, $length) = split (/\|/, $_); my ($fromConnector, $ping01) = split /\t/, $from; my ($toConnector, $ping02) = split /\t/, $to; # remove whitespace from entries $fromConnector =~ s/\s+//g; $toConnector =~ s/\s+//g; $ping01 =~ s/\s+//g; $ping02 =~ s/\s+//g; # add from connectors to respective arrays push @fromConnectors, $fromConnector; push @toConnectors, $toConnector; # add pings to respective arrays push @fromPing, $ping01; push @toPing, $ping02; } ################################################################ # # Reads in file and converts pinged conenctors to abbreviated # format required (1L, 2R etc) # ################################################################ # the number of from and to connectors are the same my $numPing = @fromConnectors; # open file that connectors are printed to my $filename = "connectorIDs.txt"; open(INFILE,"<$filename") || die "Can't open file $filename"; # put file into an array my @infile = <INFILE>; # close connectorID file close INFILE; # split the first line by spaces to get left connectors my @firstLine = split /\s+/, @infile[0]; # split the 2nd line by spaces to get right connectors my @secondLine = split /\s+/, @infile[1]; # get the number of connectors in arrays my $firstLine = @firstLine; my $secondLine = @secondLine; # initialise the arrays the converted connectors are being stored my @fromConv; my @toConv; # loop through the from connectors one at a time for (my $a = 0; $a <= $numPing; $a++) { # set the from counters so each time it looks at the # next from connector, the counter is set back my $fromLeftCounter = 1; my $fromRightCounter = 1; # read in each left connector & compare to the from connector for (my $b = 0; $b < $firstLine; $b++) { # if they are equal replace with xL and push to array # increase the counter either way if (@firstLine[$b] eq @fromConnectors[$a]) { my $leftCons = @fromConnectors[$a]; $leftCons = $fromLeftCounter."L"; push @fromConv, $leftCons; $fromLeftCounter++; } else { $fromLeftCounter++; } } # read in each right connector & compare to the from connector for (my $c = 0; $c < $secondLine; $c++) { # if they are equal replace with xR and push to array # increase the counter either way if (@secondLine[$c] eq @fromConnectors[$a]) { my $rightCons = @fromConnectors[$a]; $rightCons = $fromRightCounter."R"; push @fromConv, $rightCons; $fromRightCounter++; } else{ $fromRightCounter++; } } } # loop through the from connectors one at a time for (my $a = 0; $a <= $numPing; $a++) { # set the To counters so each time it looks at the # next To connector, the counter is set back my $toLeftCounter = 1; my $toRightCounter = 1; # read in each left connector & compare to the To connector for (my $b = 0; $b < $firstLine; $b++) { # if they are equal replace with xL and push to array # increase the counter either way if (@firstLine[$b] eq @toConnectors[$a]) { my $leftCons = @toConnectors[$a]; $leftCons = $toLeftCounter."L"; push @toConv, $leftCons; $toLeftCounter++; } else { $toLeftCounter++; } } # read in each right connector & compare to the To connector for (my $c = 0; $c < $secondLine; $c++) { # if they are equal replace with xR and push to array # increase the counter either way if (@secondLine[$c] eq @toConnectors[$a]) { my $rightCons = @toConnectors[$a]; $rightCons = $toRightCounter."R"; push @toConv, $rightCons; $toRightCounter++; } else{ $toRightCounter++; } } } # output tsv file, pings appended to line my $filename01 = "c:/CableEye/Conversion/output.txt"; open(OUTPUT,"+>>$filename01") || die "Can't open file $filename01"; print OUTPUT "\t", "\"\"", "\t", "\""; # read through each of the abbreviated arrays, pairing # the respective elements and pings. for (my $x = 0; $x < $numPing; $x++) { # if the last one do not have a space at the end if ($x eq $numPing - 1) { print OUTPUT @fromConv[$x].@fromPing[$x], ":", @toConv[$x].@to +Ping[$x], "\"", "\n"; } else { print OUTPUT @fromConv[$x].@fromPing[$x], ":", @toConv[$x].@to +Ping[$x], " "; } } # close output file close OUTPUT; # deletes the connectorID file once its been used unlink $filename;

This code reads in a table like the one below, which is inside a txt file.

+---------------------+ | General manual list | +---------------------+-----------------------------------------+----- +------------+---------------+--------+ | Type Gauge Color Referenc Id Type | FROM + | TO | Length | +---------------------------------------------------------------+----- +------------+---------------+--------+ | werww WH scr 258 ky91-02 | abc123 +1 | def123 1 | 38 | | w BU scr 258 ky91-02 | abc123 1 | + def123 2 | 38 | | WH scr 258 ky91-02 | abc123 2 | d +ef456 1 | 38 | | gg BU scr 258 ky91-02 | abc123 2 | + def456 2 | 38 | +---------------------------------------------------------------+----- +------------+---------------+--------+

It also reads in file 'ConnectorIDs.txt', which contains two lines...the first containing left connector ids and the 2nd containing right connector ids.
These are required in order to change the id's to an alias. The output is printed to output.txt in some dir.

abc123 def123 def456

Now heres the problem, as i only received printed copies of the txt files which have the table and some other junk in, i failed to notice that if the table was excessively long, it continued on the next page...with the table headers added as well. So you can see the above code will not collect the data needed for a second table, how do i make it so it does?

The table still has the same features, with 'General manual list' as a title etc.

All guidance/advice is appreciated

Thanks, Steve

update (broquaint): added <readmore> tag

Replies are listed 'Best First'.
Re: read file twice
by tachyon (Chancellor) on Oct 27, 2003 at 13:59 UTC

    If you don't want to change your main code just write a simple script to pre-process the data and concatenate the second page onto the first. That way your data will be as you expected when you wrote the script. Quick and dirty but probably the easiest fix.

    All you need to do is work out the point(s) of difference between a single page table and a multipage one. For example it seems from what you present that the data fields always match m/^\|\s+[a-z]/ ie a | spaces then a lower case letter code (the headers, blank lines etc don't) so you could do:

    perl -ne 'print if m/^\|\s+[a-z]/' infile > outfile

    This will put all the data rows into the outfile (no headers or anything else). Mod the main script so it does not expect to skip headers.....

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: read file twice
by delirium (Chaplain) on Oct 27, 2003 at 14:40 UTC
    It looks like it would be easy to ignore lines that start with + or contain "General manual list" or "Color Referenc", meaning you could just change the top of your code to something like:

    use strict; my @fromConnectors; my @toConnectors; my @fromPing; my @toPing; while (<>) { next if /^\+|General manual list|Color Referenc/; my ($misc1, $misc2, $from, $to, $length) = split (/\|/, $_); my ($fromConnector, $ping01) = split /\t/, $from; my ($toConnector, $ping02) = split /\t/, $to; ## ...etc.