Reputation: 27
PIN W[2]
DIRECTION INPUT ;
USE SIGNAL ;
PORT
LAYER M5
RECT 0.115 0.59 0.175 1.22 ;
RECT 0.06 0.98 0.175 1.22 ;
RECT 0.335 1.16 0.395 1.44 ;
RECT 0.51 0.57 0.63 0.65 ;
LAYER M3
RECT 0.115 0.59 0.175 1.22 ;
RECT 0.06 0.98 0.175 1.22 ;
RECT 0.335 1.16 0.395 1.44 ;
RECT 0.51 0.57 0.63 0.65 ;
LAYER M1
RECT 0.115 0.59 0.175 1.22 ;
RECT 0.06 0.98 0.175 1.22 ;
RECT 0.335 1.16 0.395 1.44 ;
RECT 0.51 0.57 0.63 0.65 ;
LAYER M6
RECT 0.115 0.59 0.175 1.22 ;
RECT 0.06 0.98 0.175 1.22 ;
RECT 0.335 1.16 0.395 1.44 ;
RECT 0.51 0.57 0.63 0.65 ;
END
END W[2]
What I wanted is to search for the number starting with LAYER M (having greatest number in the above) and print only the lines starting with RECT below it. Please refer the below snippet for how the required lines should look like.
PIN W[2]
DIRECTION INPUT ;
USE SIGNAL ;
PORT
LAYER M6
RECT 0.115 0.59 0.175 1.22 ;
RECT 0.06 0.98 0.175 1.22 ;
RECT 0.335 1.16 0.395 1.44 ;
RECT 0.51 0.57 0.63 0.65 ;
END
END W[2]
Upvotes: 1
Views: 110
Reputation: 1578
I find it easier to not step through the file twice, and line numbers tend to confuse me, so I've decided to post my take on it.
Good luck and feel free to comment any improvements to edit in!
#!/usr/bin/env perl
use strict;
use warnings;
open my $fh, '<', 'input.txt' or die "Cannot open file < '$input_fn': $!";
my %layers;
my $layer_number;
my ( $begin_block, $end_block );
while ( my $line = <$fh> ){
if ( $line =~ /^[\s\t]*LAYER\s+M([0-9]+)/ ){
$layer_number = $1;
}
# layer number not set: Add to begin block
unless ( $layer_number ){
$begin_block .= $line;
next;
}
# END: no further layers. Just slurp it and done.
if ( $line =~ /END/ ){
my $slurped_end = do{ local $/; <$fh>; };
$end_block = $line . $slurped_end;
last;
}
# store line for this block
$layers{ $layer_number } .= $line;
}
close $fh;
# find highest block, reassemble and print
my $highest_block_number = ( sort{ $a <=> $b } keys %layers )[-1];
print $begin_block . $layers{ $highest_block_number } . $end_block;
Upvotes: 2
Reputation: 40778
Here is an example. It scans the lines of the file file.txt
twice. The first time it records the maximum layer number, and the second time it prints lines if it is not a layer, or if it is the maximum layer block:
use strict;
use warnings;
my $fn = 'file.txt';
my @lines;
my $max_layer_num = 0;
open ( my $fh, '<', $fn ) or die "Could not open file '$fn': $!";
while (<$fh>) {
push @lines, $_;
if ( /^LAYER\s+M(\d+)/ ) {
$max_layer_num = $1 if $1 > $max_layer_num;
}
}
close $fh;
my $i = 0;
while ( $i <= $#lines ) {
$_ = $lines[$i];
if( /^LAYER\s+M(\d+)/ ) {
if ( $1 != $max_layer_num ) {
while (1) {
$i++;
last if $i > $#lines;
$_ = $lines[$i];
last if $_ !~ /^\s+RECT/;
}
next;
}
}
print; $i++
}
Upvotes: 1