在某些特殊情况下需要从删除中保存一行 [英] Need to save a single line from delete on some special condition
问题描述
我编写了一个 perl 代码,它能够在满足方向:输出"条件时从包含max_transition"的文件 (IN_FILE) 中搜索和删除一行.删除该行后,代码会将修改后的文件写入不同的位置.
现在我需要删除max_transition"行,当direction : output"条件满足时,以及在该特定引脚组中找到单词timing"的位置.
IN_FILE,具有输出引脚HIZIBI_79"、HIZIBI_78 和 HIZIBI.运行脚本后,不应从引脚HIZIBI_79"、HIZIBI_78"中删除max_transition"行,因为该引脚组没有时序".只有max_transition"行会从引脚HIZIBI"中删除,它有一个时间"组.
知道如何实施吗?
输出文件应该看起来像 OUT_FILE
使用警告;使用严格;我的 $inputfile = $ARGV[0];# 输入库文件如果($#ARGV!=0){打印 "USAGE :: perl max_tran_update.pl <<LIB_FILE>> \n\n";退出(1);}我的 $cmd = "mkdir tmpdir;";系统 ($cmd);我的 $iline;我的 $flag_outpin = 0;我的 $out_pin_flag = 0;打开 (INFILE,"<","$inputfile") ||die "无法打开输入 LIB 文件";open (my $OPFILE,">","tmpdir/input_lib.lib") ||死无法打开输入文本文件";while ($iline = ){chomp $iline;打印 $OPFILE "$iline\n";if (($iline =~m/^\s*direction\s*:\s*output\s*;/g)){$flag_outpin=1;while ($iline = ){if (($iline =~m/^\s*direction\s*:\s*input\s*;/g)){$flag_outpin=0;}if (($iline =~m/^\s*direction\s*:\s*output\s*;/g)){$flag_outpin=1;}if (($iline =~m/^\s*max_transition\s*:/g) && ($flag_outpin == 1)){$iline =~ s/$iline//g ;}别的{打印 $OPFILE "$iline";}}}}关闭文件;关闭 $OPFILE;
IN_FILE
单元格 (lib_1) {不要使用:真;dont_touch : 真;引脚(HIZIBI_IN_1"){方向:输入;时钟:真;最大转换:1;电容:12;}销(HIZIBI_79"){方向:输出;最大转换:10;最小电容:3;}引脚(HIZIBI_IN_1"){方向:输入;时钟:真;最大转换:1;电容:1;}销(HIZIBI_78"){方向:输出;最大转换:10;最小电容:34;电容:34;}销(HIZIBI"){方向:输出;时钟:真;最大转换:20;related_power_pin : VDD ;related_ground_pin : VSS ;计时(){cell_fall (into_f1) {index_1("1,2,3,4,5");index_2("1,2,3,4,5");值("13, 13, 14, 16, 18",\"13, 14, 15, 16, 19",\"14, 15, 16, 17, 20",\"15, 15, 16, 18, 20",\"15, 16, 17, 18, 21") ;}}}}
OUT_FILE
<预><代码>单元格(lib_1){不要使用:真;dont_touch : 真;引脚(HIZIBI_IN_1"){方向:输入;时钟:真;最大转换:1;电容:12;}销(HIZIBI_79"){方向:输出;最大转换:10;最小电容:3;}引脚(HIZIBI_IN_1"){方向:输入;时钟:真;最大转换:1;电容:1;}销(HIZIBI_78"){方向:输出;最大转换:10;最小电容:34;电容:34;}销(HIZIBI"){方向:输出;时钟:真;related_power_pin : VDD ;related_ground_pin : VSS ;计时(){cell_fall (into_f1) {index_1("1,2,3,4,5");index_2("1,2,3,4,5");值("13, 13, 14, 16, 18",\"13, 14, 15, 16, 19",\"14, 15, 16, 17, 20",\"15, 15, 16, 18, 20",\"15, 16, 17, 18, 21") ;}}}}如果您解析文件以一次处理一个 pin { ... }
部分,这会变得容易得多.这段代码似乎可以解决问题,但它可能很脆弱,很可能会在更复杂的输入上中断.
#!/usr/bin/perl使用严格;使用警告;# $counter 将包含不匹配的 { 字符数# 我们已经看到.如果它是一个正数,那么我们处于# pin 部分,我们不会输出任何东西,直到我们到达# 该部分的结尾.我的 $counter;# 包含我们当前 pin 部分的内容.我的 $pin = '';# 从 STDIN 一次读取一行而 (<>) {# 如果我们不在 pin block 中,那么# 只打印这一行.如果 (!$counter 和 !/\bpin\b/) {打印;下一个;}# 将 $counter 增加 { 行中的字符数$counter += tr/{/{/;# 按照行中} 字符的数量减少 $counter$counter -= tr/}/}/;# 将当前行追加到 $pin$pin .= $_;# 如果 $counter 是 0 那么我们就到了一个 pin 的末尾# 堵塞.该块的文本将在 $pin 中.如果(!$计数器){# 如果 $pin 包含 "directions : output" 和 "timings"...if ($pin =~/direction\s*:\s*output/和 $pin =~/timing\s*/) {# ... 然后从 $pin 中删除max_transitions"行$pin =~ s/\s*max_transition\s*:.*\n//;}# 打印当前的 $pin 部分打印 $pin;# 并重置 $pin 以开始下一部分.$pin = '';}}
我也把它写成一个 Unix 过滤器.也就是说,它从STDIN
读取并写入STDOUT
.这比硬编码文件名更灵活.你会像这样运行它:
$ my_pin_filter <in_file >tmpdir/input_lib.lib
I have written a perl code which is able to search and delete a line from a file (IN_FILE) which contains "max_transition",when "direction : output" condition will satisfy. After deleting the line the code writes the modified file into a different location.
Now I need to delete the line "max_transition" when the "direction : output" condition will satisfy as well as where it will find word "timing" in that particular pin group.
IN_FILE, has output pin "HIZIBI_79", HIZIBI_78 and HIZIBI. After running the script "max_transition" line should not be deleted from pin "HIZIBI_79", HIZIBI_78", because this pin group do not have "timing". Only "max_transition" line would be deleted from pin "HIZIBI", it has a "timing" group.
Any idea how to implement it?
Output file should be look like OUT_FILE
use warnings;
use strict;
my $inputfile = $ARGV[0]; # input lib FILE
if ($#ARGV!=0)
{
print "USAGE :: perl max_tran_update.pl <<LIB_FILE>> \n\n" ;
exit(1);
}
my $cmd = "mkdir tmpdir;";
system ($cmd);
my $iline;
my $flag_outpin = 0;
my $out_pin_flag = 0;
open (INFILE,"<","$inputfile") || die "Can not open Input LIB File";
open (my $OPFILE,">","tmpdir/input_lib.lib") || die "Can not open Input Text File";
while ($iline = <INFILE>)
{
chomp $iline;
print $OPFILE "$iline\n";
if (($iline =~m/^\s*direction\s*:\s*output\s*;/g))
{
$flag_outpin=1;
while ($iline = <INFILE>)
{
if (($iline =~m/^\s*direction\s*:\s*input\s*;/g))
{
$flag_outpin=0;
}
if (($iline =~m/^\s*direction\s*:\s*output\s*;/g))
{
$flag_outpin=1;
}
if (($iline =~m/^\s*max_transition\s*:/g) && ($flag_outpin == 1))
{
$iline =~ s/$iline//g ;
}
else
{
print $OPFILE "$iline";
}
}
}
}
close INFILE;
close $OPFILE;
IN_FILE
cell (lib_1) {
dont_use : true ;
dont_touch : true ;
pin ("HIZIBI_IN_1") {
direction : input ;
clock : true ;
max_transition : 1 ;
capacitance : 12 ;
}
pin ("HIZIBI_79") {
direction : output ;
max_transition : 10;
min_capacitance : 3 ;
}
pin ("HIZIBI_IN_1") {
direction : input ;
clock : true ;
max_transition : 1 ;
capacitance : 1 ;
}
pin ("HIZIBI_78") {
direction : output ;
max_transition : 10;
min_capacitance : 34 ;
capacitance : 34 ;
}
pin ("HIZIBI") {
direction : output ;
clock : true ;
max_transition : 20;
related_power_pin : VDD ;
related_ground_pin : VSS ;
timing () {
cell_fall (into_f1) {
index_1("1,2,3,4,5") ;
index_2("1,2,3,4,5") ;
values("13, 13, 14, 16, 18",\
"13, 14, 15, 16, 19",\
"14, 15, 16, 17, 20",\
"15, 15, 16, 18, 20",\
"15, 16, 17, 18, 21") ;
}
}
}
}
OUT_FILE
cell (lib_1) {
dont_use : true ;
dont_touch : true ;
pin ("HIZIBI_IN_1") {
direction : input ;
clock : true ;
max_transition : 1 ;
capacitance : 12 ;
}
pin ("HIZIBI_79") {
direction : output ;
max_transition : 10;
min_capacitance : 3 ;
}
pin ("HIZIBI_IN_1") {
direction : input ;
clock : true ;
max_transition : 1 ;
capacitance : 1 ;
}
pin ("HIZIBI_78") {
direction : output ;
max_transition : 10;
min_capacitance : 34 ;
capacitance : 34 ;
}
pin ("HIZIBI") {
direction : output ;
clock : true ;
related_power_pin : VDD ;
related_ground_pin : VSS ;
timing () {
cell_fall (into_f1) {
index_1("1,2,3,4,5") ;
index_2("1,2,3,4,5") ;
values("13, 13, 14, 16, 18",\
"13, 14, 15, 16, 19",\
"14, 15, 16, 17, 20",\
"15, 15, 16, 18, 20",\
"15, 16, 17, 18, 21") ;
}
}
}
}
This gets a lot easier if you parse the file to deal with one pin { ... }
section at a time. This code seems to do the trick, but it's probably fragile and might well break on more complex input.
#!/usr/bin/perl
use strict;
use warnings;
# $counter will contain the number of unmatched { characters
# we have seen. If it's a positive number then we are in a
# pin section and we won't output anything until we get to
# the end of that section.
my $counter;
# Contains the contents of our current pin section.
my $pin = '';
# Read a line at a time from STDIN
while (<>) {
# If we're not in a pin block, then
# just print the line.
if (!$counter and !/\bpin\b/) {
print;
next;
}
# Increment $counter by the number of { characters in the line
$counter += tr/{/{/;
# Decrement $counter by the number of } characters in the line
$counter -= tr/}/}/;
# Append the current line to $pin
$pin .= $_;
# If $counter is 0 then we've just got to the end of a pin
# block. The text of that block will be in $pin.
if (!$counter) {
# If $pin contains "directions : output" and "timings"...
if ($pin =~ /direction\s*:\s*output/ and $pin =~ /timing\s*/) {
# ... then remove the "max_transitions" line from $pin
$pin =~ s/\s*max_transition\s*:.*\n//;
}
# Print the current $pin section
print $pin;
# And reset $pin to start the next section.
$pin = '';
}
}
I've also written this as a Unix filter. That is, it reads from STDIN
and writes to STDOUT
. This is more flexible than hard-coding filenames. You would run it like this:
$ my_pin_filter < in_file > tmpdir/input_lib.lib
这篇关于在某些特殊情况下需要从删除中保存一行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!