我有一个输入源,如下所示。我想要做的是将每个Layer
行的数值捕获到一个数组中,然后打印出最大值。
MACRO cell_1
size 0.1 by 0.1 ;
pin a
(....same topology as pin vcc)
END a
pin b
(.....same topology as pin vcc)
END b
Pin vcc
aaaa
bbbb
Port
Layer m2 ;
END
CCC
DDD
Port
Layer m1 ;
END
EEE
FFF
Port
Layer m0 ;
END
END vcc
pin d
(....same topology as pin vcc)
END d
END cell_1
MACRO cell_2
(repeated)
END cell_2
foreach my $file ( @files ) { # @files = multiple path of abc/def/fgh/cell_lef
open( INFILE, "<$file" ) || die "Can not open stdcell_file\n";
my @lines = <INFILE>;
close INFILE;
$init = 1;
$delimiter =~ /^$/; # between each MACRO. haven't utilize this yet
foreach (@lines) {
if ( $init ) {
$path = 1;
$init = 0;
@num = ();
}
if ( $path ) {
if ( /MACRO\s+(\S+) /) {
$cellname = $1; print "$cellname\n";
}
if ( /SIZE\s+(\S+)\s+(\S+)\s+(\S+)/ ) {
$footprint_x = $1;
$footprint_y = $3;
print "$footprint_x $footprint_y\n";
}
if ( /PIN vcc/ .. /END vcc/ ) {
#grab the highest value from layer (m*)
#print "max layer = m*"
}
$init = 1;
}
}
}
cell_1
0.1 0.1
m2
cell_2
0.2 0.2
m3
if ( /PIN vcc/../END vcc/ ) {
if ( /LAYER\s+m(\S+) / ) {
push(@num, $1);
print "@num";
}
}
到目前为止我的代码存在的问题是,当我打印@num
的值时,所有值都以字符串(210
)而不是单个元素连接在一起:2 1 0
- 所以我无法进行排序以获得最大值。
更新 :我不确定如何将while
集成到我的代码中,因为我使用foreach作为我的主循环
答案 0 :(得分:2)
您的代码正在捕获数字,只是您正在打印整个数组。打印数组时,Perl对数组元素的默认分隔符是""
,即没有 - 所以,它看起来像一个单独的字符串,但是每个字符串旁边都打印了三个(或多个)元素其他没有分隔符。
您可以使用while (<>) {
在Unix过滤器样式中逐行迭代输入。您可以打开&#34;扫描模式&#34;当&#34; PIN vcc&#34;找到并在&#34; END vcc&#34;找到了。之后,使用正则表达式搜索图层线,但始终使用&#39;扩展模式&#39; /x
所以你可以在你的正则表达式中使用空格。
由于用于切换模式和捕获图层编号的正则表达式是互斥的,因此您可以在检查成功后让其他检查发生 - 只要知道如果将来的更改导致重叠的情况,您需要做当其中一个正则表达式成功时,next
。
最后,List::Util是一个核心模块,所以你也可以从中获取max function;
use v5.12;
use warnings;
use List::Util qw( max );
my @num ;
my $scanning = 0;
while (<>) {
$scanning = 1 if /PIN vcc/ ;
$scanning = 0 if /END vcc/ ;
next unless $scanning ;
push @num, $1 if /Layer \s+ m (\d+) /x ;
}
say "Max layer number found: ", max(@num) ;
答案 1 :(得分:1)
或者只需使用sort
功能即可。
my @values ;
while (<DATA>)
{
push (@values , $1) if (/Layer\s+m(\d+)\s;/);
}
my ($max) = sort{$b <=> $a} @values ;
print "$max\n";
__DATA__
Pin vcc
aaaa
bbbb
Port
Layer m3 ;
END
CCC
DDD
Port
Layer m1 ;
END
EEE
FFF
Port
Layer m0 ;
END
使用sort
函数并将第一个结果存储到包含变量$max
的列表中。
答案 2 :(得分:0)
my @data = <DATA> ;
my @num ;
foreach (@data) {
push @num, $1 if /Layer\s+m(\S+)/ ;
}
# home made max() - sorts an anonymous array and prints the last element
print [ sort { $a <=> $b } @num ]->[-1] , "\n" ;
__DATA__
Pin vcc
aaaa
bbbb
Port
Layer m2 ;
END
CCC
DDD
Port
Layer m1 ;
END
EEE
FFF
Port
Layer m0 ;
END
END vcc
答案 3 :(得分:0)
使用map
从文件中提取数字。 sort
数字并获得最大数量。
#!/usr/bin/perl
use strict;
use warnings;
my $max = (sort{$b <=> $a }map{/Layer\s+m(\d+)/} <DATA>)[0];
print $max,"\n";
__DATA__
Pin vcc
aaaa
bbbb
Port
Layer m3 ;
END
CCC
DDD
Port
Layer m1 ;
END
EEE
FFF
Port
Layer m0 ;
END
答案 4 :(得分:0)
首先,如果您只查找最大值,则无需存储所有值;第二,在循环结束后打印最大值,
my $max = "-inf";
if (/PIN vcc/ .. /END vcc/) {
$max = $1 if /LAYER\s+m(\S+)/ and $max < $1;
}
# ..
print $max, "\n";