#regex #perl
#регулярное выражение #perl
Вопрос:
Я написал код на perl, который способен выполнять поиск и удалять строку из файла (IN_FILE), который содержит «max_transition», когда выполняется условие «направление: вывод». После удаления строки код записывает измененный файл в другое местоположение.
Теперь мне нужно удалить строку «max_transition», когда будет выполнено условие «направление: вывод», а также где будет найдено слово «timing» в этой конкретной группе выводов.
IN_FILE, имеет выходной вывод «HIZIBI_79», HIZIBI_78 и HIZIBI. После запуска скрипта строка «max_transition» не должна удаляться из pin-кода «HIZIBI_79», «HIZIBI_78», потому что у этой группы pin-кодов нет «timing». Из pin-кода «HIZIBI» будет удалена только строка «max_transition», у нее есть группа «timing».
Есть идеи, как это реализовать?
Выходной файл должен выглядеть как 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>> nn" ;
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 "$ilinen";
if (($iline =~m/^s*directions*:s*outputs*;/g))
{
$flag_outpin=1;
while ($iline = <INFILE>)
{
if (($iline =~m/^s*directions*:s*inputs*;/g))
{
$flag_outpin=0;
}
if (($iline =~m/^s*directions*:s*outputs*;/g))
{
$flag_outpin=1;
}
if (($iline =~m/^s*max_transitions*:/g) amp;amp; ($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") ;
}
}
}
}
Комментарии:
1. можете ли вы еще раз проверить требуемый вывод?. timing() не удаляется..
2. должна быть удалена строка «max_transition», а не блок синхронизации. «max_transition» должен быть удален, в какой группе контактов код найдет группу синхронизации. пожалуйста, смотрите, из pin HIZIBI удален max_transition.
3. Ваше простое решение «прочитайте строку, не печатайте ее при выполнении условий» не будет работать с вашим новым требованием, так как
timing(
это происходит после строки, которую вы хотите удалить. Вам придется переписать свой код, чтобы прочитать одинpin(..) { ... }
раздел целиком, решить, какие строки удалить, а затем перенести это в выходные данные. Поскольку у вас есть несколько операторов блочного типа, вам нужно будет либо посчитать открытые скобки, либо написать реальный анализатор для данного синтаксиса.4. Код намного легче читать, если он имеет правильный отступ. Я только что исправил это для кода в этом вопросе. Пожалуйста, делайте это сами в будущем.
Ответ №1:
Это становится намного проще, если вы анализируете файл, чтобы иметь дело с одним pin { ... }
разделом за раз. Этот код, похоже, справляется с задачей, но он, вероятно, хрупкий и вполне может сломаться при более сложном вводе.
#!/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 !/bpinb/) {
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 =~ /directions*:s*output/ and $pin =~ /timings*/) {
# ... then remove the "max_transitions" line from $pin
$pin =~ s/s*max_transitions*:.*n//;
}
# Print the current $pin section
print $pin;
# And reset $pin to start the next section.
$pin = '';
}
}
Я также написал это как фильтр Unix. То есть оно считывает из STDIN
и записывает в STDOUT
. Это более гибко, чем жестко запрограммированные имена файлов. Вы бы запустили его следующим образом:
$ my_pin_filter < in_file > tmpdir/input_lib.lib
Комментарии:
1. Это лучший ответ @Dave Cross. Я считаю, что вы сделали наилучшим образом, как это должно быть. Нет, это не «хрупкий» код, отвечающий всем условиям, которые я здесь не упомянул. Спасибо, сэр 🙂
2. Мне очень, очень жаль, я должен нажать на галочку рядом с ответом. Только что я это сделал. Еще раз извините.
Ответ №2:
Попробуйте эту командную строку Perl
perl -0777 -ne ' s/(pins*(". ?"?)s {. ?})/$x=$1;if($x=~m!timings*()! and $x=~m!direction : output!){$x=~s!^s*max_transition. ?n!!mg};$x/gse ; print ' anny_in.txt
Результаты:
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") ;
}
}
}
}
Комментарии:
1. Уважаемый stack0114106, После запуска команды я получаю «timing: событие не найдено» из командной строки.
2. @anny..no у меня это сработало .. anny_in — это входной файл.. Попробуйте еще раз
3. Дорогой stack0114106, я пробовал несколько раз, но все еще получаю ту же проблему. Это связано с тем, что мы используем другую версию ОС? Я использую его в CentOS 6.7.
4. я запускаю его в cygwin .. можете ли вы проверить, присутствует ли
r
?.. если да, удалите это и повторите попытку?5. r отсутствует