How to read data that appear in next line?

My problem is to read data in the next line for input 2 same like we can read data as input 1. I expect that we can read input 2 as input 1.

Here is input 1:

A1 clkout n0 vss vss nx 0.408 0.02 $$UNI
A2 clkout n2 vss vss nx 0.612 0.02 $$UNI
A3 clkin  n1 vss vss nx 0.34 0.02 $$UNI

Here is input 2:

A1 clkout n0 vss vss nx
+ 0.408 0.02 $$UNI
A2 clkout n2 vss vss nx 0.612  
+ 0.02 $$UNI
A3 clkin  n1 vss vss
+ nx 0.34 0.02 $$UNI 

The code to get the 6th column is shown below:

while (<SN>) {
        chomp;
        next if (/^\$\s*\#+/);

        if (/^M/) {

            my @m = split (/\s+/, $_);

            if ($m[6] =~ /\=/) {
                $m[6] = $m[7];
               $m[6] =~ s/W\=(\S+)u/$2/;

            }

            $CSV{cell}{$c}{tx}{$m[5]}{count} += 1;
            $CSV{cell}{$c}{tx}{$m[5]}{totZ}  += $m[6];

            if ($opt_grid_um) { 
               $g = $m[6] / $G{grid_um};
            } else {
               $g = $m[6];
            }
       close (SN);
     }

I already tried to get data for the 6th column from input 1 but cannot read for input 2. I think there is some error at this line: $m[6] =~ s/W\=(\S+)u/$2/;

My expected result is to read input 2 format as input 1 by ignoring the '+' sign in front of the second line. Then, the script can read data in each column as input 1.

Upvotes: 1

Views: 58

Answers (1)

zdim
zdim

Reputation: 66873

A line with + is a continuation line, that completes the "full line" when added to the previous one. Then we can process the completed line (extract the seventh field). If the line doesn't start with a + then it's the first part of the next line to be assembled.

Also, if there may be unbroken lines then they aren't followed by a line with + and we need to also check whether the previous line started with + (when the current line doesn't).

In order to avoid tap dancing around the first line, when nothing is initialized (then if statements would have to always test for the first line!), I first read one line and only then enter the loop.

use warnings;
use strict;
use feature 'say';

my $file = shift // die "Usage: $0 file\n";  #/    
open my $fh, '<', $file or die "Can't open $file: $!";

my (@data, $full_line);
my $prev_line = <$fh>;   # Start it off -- the first line

while (my $line = <$fh>) { 
    chomp $line;

    # Continuation line?
    if ($line =~ /^\s*\+\s*(.*)/) { 
        $full_line = $prev_line . ' ' . $1; 
    }   
    # Or was the previous line indeed one with a +
    elsif ($prev_line =~ /^\s*\+/) {
        $prev_line = $line;
        next;
    }   
    # If not, then it was a complete line on its own, ready to process
    else {
        $full_line = $line;
    }   

    push @data, (split ' ', $full_line)[6];

    $prev_line = $line;
}

say for @data;

Some reasonable assumptions are used here, one being major: that a "full" line may be broken into at most two lines; so there can only be one + line. This is easy to relax if need be.

This prints expected output with the provided sample file.

I don't understand the shown code which, among other things, tests for = etc. So I simply take the stated 7th column.

Upvotes: 2

Related Questions