perl:使脚本像perl单行程一样高效

时间:2015-06-12 16:34:09

标签: perl

我能够在命令行上执行此操作并且它可以正常工作:

~/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;
}

2 个答案:

答案 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;