【问题标题】:format the following result file into a tabular format using Perl使用 Perl 将以下结果文件格式化为表格格式
【发布时间】:2015-06-25 04:20:12
【问题描述】:

我有一个问题,我还是 Perl 新手。

我只是想问一下如何将以下结果文件格式化为 Excel 可读格式(比如说 CSV)。

结果文件示例。 llq1_dly.mt0

$MEAS COMMANDS SOURCE='llq1_dly.meas' DB FILE='clk_top_45h_lpe_sim.fsdb'
.TITLE '**-------------'
    tdrll10_0        tdfll10_0        tdrll10_1        tdfll10_1        tdrll10_2        tdfll10_2        tdrll10_3
 2.106560e-10     1.990381e-10     2.102583e-10     1.986280e-10     2.095036e-10     1.978480e-10     2.083813e-10

进入以下文件,结果如下所示

llq1_dly,tdr,tdf,
ll10_0,2.106560e-10,1.990381e-10,
ll10_1,2.102583e-10,1.986280e-10,
ll10_2,2.095036e-10,1.978480e-10,
ll10_3,2.083813e-10,1.967019e-10,
...

或更可能是这个(与工程科学记数法兼容):

llq1_dly,tdr,tdf,
ll10_0,210.6560e-12,199.0381e-12,
ll10_1,210.2583e-12,198.6280e-12,
ll10_2,209.5036e-12,197.8480e-12,
ll10_3,208.3813e-12,196.7019e-12,
...

【问题讨论】:

    标签: string perl csv string-formatting


    【解决方案1】:

    这是一个产生您要求的输出的程序。我通常不赞成为 OP 没有尝试自己编写解决方案的问题提供答案,但这个问题让我很感兴趣。

    很可能这可以写得更简单,但你没有说输入的哪些部分是不变的。例如,我已经编写了它,以便可以有任意数量的具有任意名称的不同列,而不仅仅是 tdrtdf 每次。因为我不得不猜测每个标题的尾随部分以ll 结尾,例如tdrll10_0tdrll10_0。如果这是错误的,那么您将需要另一种拆分字符串的方法。

    我已经编写了程序,以便它从DATA 文件句柄中读取。我相信您能够编写 open 语句来读取正确的输入文件?

    希望对你有帮助

    use strict;
    use warnings;
    use 5.010;
    
    use Number::FormatEng 'format_eng';
    Number::FormatEng::use_e_zero();
    
    my $fh = \*DATA;
    
    my ($source, @headers, @values);
    while ( <$fh> ) {
      if ( /SOURCE=(?|'([^']+)'|"([^"]+)")/ ) { #' code highlighting fix
        ($source = $1) =~ s/\.[^.]*\z//;
      }
      elsif ( /^\.TITLE/ ) {
        @headers = split ' ', <$fh>;
        @values  = split ' ', <$fh>;
        last;
      }
    }
    
    my @title = ( $source );
    my (%headers, @table, @line);
    for my $i ( 0 .. $#headers) {
      my @fields = split /(?=ll)/, $headers[$i];
      if ( $headers{$fields[0]} ) {
        push @table, [ @line ];
        @line = ();
        %headers = ();
      }
      ++$headers{$fields[0]};
      push @line, $fields[1] if @line == 0;
      push @line, format_eng($values[$i]);
      push @title, $fields[0] unless @table;
    }
    print "$_," for @title;
    print "\n";
    
    for ( @table ) {
      print "$_," for @$_;
      print "\n";
    }
    
    __DATA__
    $MEAS COMMANDS SOURCE='llq1_dly.meas' DB FILE='clk_top_45h_lpe_sim.fsdb'
    .TITLE '**-------------'
        tdrll10_0        tdfll10_0        tdrll10_1        tdfll10_1        tdrll10_2        tdfll10_2        tdrll10_3
     2.106560e-10     1.990381e-10     2.102583e-10     1.986280e-10     2.095036e-10     1.978480e-10     2.083813e-10
    

    输出

    llq1_dly,tdr,tdf,
    ll10_0,210.656e-12,199.0381e-12,
    ll10_1,210.2583e-12,198.628e-12,
    ll10_2,209.5036e-12,197.848e-12,
    

    【讨论】:

    • @Borodin 你能解释一下代码高亮修复部分的作用吗?我还不熟悉正则表达式。谢谢
    • @Meeyaw:检查当前行是否包含SOURCE= 后跟单引号或双引号字符串,并捕获(在$1 中)引号内的字符串。注释只是一个单引号,以防止代码荧光笔混淆:没有它,它认为程序的其余部分都是字符串文字
    猜你喜欢
    • 2014-11-08
    • 2015-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-16
    • 1970-01-01
    • 1970-01-01
    • 2022-10-02
    相关资源
    最近更新 更多