我能够在命令行上执行此操作并且它可以正常工作:
~/Tools/perl/edif_extr_cell.pl design.edif nmos1p8v | perl -p -e 's/^/\n/ if /portImplementation|figure\s+device/;' | perl -n -000 -e 'print if /portImplementation/;'
(基本上,提取EDIF文件的一部分)。
现在,我想对此做一个实用工具。我的脚本在下面。问题:这段代码可以更有效吗?如果觉得它非常不优雅。我可以在命令行上轻松地管道流,但是在脚本中,我感到迷茫。
#!/usr/bin/perl -w -p
BEGIN{ $file = '';}
s/^/\n/ if /portImplementation|figure\s+device/;
$file .= $_;
END{
$cmd = q{\rm -f /tmp/dump}.$$.'.txt';
system( $cmd );
open( OUT, ">/tmp/dump$$.txt");
print OUT $file;
close OUT;
$out = `perl -n -000 -e 'print if /portImplementation/;' /tmp/dump$$.txt`;
system( $cmd );
print $out;
}
答案 0 :(得分:3)
如果我理解正确,你希望能够做到
~/Tools/perl/edif_extr_cell.pl design.edif nmos1p8v | myfilter
理想情况下,您将两个Perl脚本合并为一个,而不是让一个脚本启动两个Perl实例,但由于$/
的更改(通过-00
,这变得相当困难})因为你在第一个过滤器中插入换行符。
最简单的答案:
#!/bin/sh
perl -pe's/^/\n/ if /portImplementation|figure\s+device/' |
perl -00ne'print if /portImplementation/'
您似乎在尝试在Perl中编写等效的sh
脚本。它看起来如下:
#!/usr/bin/perl
use strict;
use warnings;
use IPC::Open qw( open3 );
# open3 has issues with lexical file handles.
pipe(local *PIPE_READER, local *PIPE_WRITER)
or die($!);
my $pid1 = open3('<&STDIN', '>&PIPE_WRITER', '>&STDERR',
'perl', '-pes/^/\n/ if /portImplementation|figure\s+device/');
my $pid2 = open3('<&PIPE_READER', '>&STDOUT', '>&STDERR',
'perl', '-00neprint if /portImplementation/');
waitpid($pid1);
waitpid($pid2);
我通常建议使用IPC :: Run3或IPC :: Run来启动和连接子进程,但是在这种特殊情况下,低级open3
可以很好地完成这项工作。
答案 1 :(得分:0)
我从GitHub下载了一个随机的EDIF文件,在其上运行以下脚本会得到与您的代码相同的输出:
#! /usr/bin/perl
use warnings;
use strict;
my @buffer;
my $found;
my $prepend = q();
while (<>) {
if (/portImplementation|figure\s+device/) {
if ($found && @buffer) {
print $prepend, @buffer;
$prepend = "\n";
}
undef $found;
@buffer = ();
}
$found ||= /portImplementation/;
push @buffer, $_;
}
# Don't forget to output the last paragraph!
print $prepend, @buffer if $found && @buffer;