2

以下の入力形式があります。これらのデータの表形式を作成したいと思います。

CELL    = "abc"
        "model"         "abc"
        "description"   "qwerty+keypad with slide"
**tech**
        size    (big \$l \$w m)
        termOrder         (x y z)
        namePrefix        "S"
        prop       (nil \$l l \$w w)
    **spec**
        term      (nil C \:1 B \:2 E \:3)
        termOrder         (x y z)
***********************************************************
 CELL    = "efg"
        "model"        "efg"
        "description"  "touchscreen+qwerty no slide"
**tech**
        size    (small \$l \$w m)
        termOrder         (x y z)
        namePrefix        "S"
        prop       (nil \$l l \$w w)
 **spec**
        term          (nil x \:1 y \:2 z \:3)
        termOrder         (x y z)

ヘッダーとして左側に名前があり、右側のデータがその値であるテーブルが必要です。

.                                         tech                            spec   
CELL   model   description   size   termOrder   namePrefix  prop  termOrder Term       

これらはヘッダーであり、これらのヘッダーの下に対応する値が必要です。別の種類の集計に使用したこのコードを使用してみました。

my $pr      = "%-12s";  
my @headers = qw/............../;  
my %names;

while (<DATA>) {          

    chomp;          
    my $line = <DATA>;          
    %{$names{$_}} = split /=|\s+/, $line;  
} 

printf $pr x @headers . "\n", @headers;  

for (keys %names) {

    my @ds = ($_);          
    for my $k (@headers[1 .. $#headers]) {     

        my $v = $names{$_}->{$k};                 
        push @ds, $v ? $v : '-';
    }         
    printf $pr x @ds . "\n", @ds;
 } 

これでは必要な結果が得られないため、親切にこれを手伝ってください。

4

1 に答える 1

3

これは実際には最も簡単な作業ではなく、いつものように、それを行うには複数の方法があります。これが1つです。ご不明な点がございましたら、コードが多すぎてすべてを説明できないため、お気軽にお問い合わせください。

ただし、それが私のタスクである場合、これらすべての幅の計算を取り除くために出力形式としてHTMLを選択します。また、これらのテーブルを並べ替えるための快適なJSツールもあります。あなたが本当にテキストだけでこのようなことをしたいのなら、多分「古き良きフォーマット」があなたのためです。;)

コード

#!/usr/bin/env perl

use strict;
use warnings;
use feature 'switch';
use List::Util 'sum';

# preparations
my @blocks; # array for all data block
my $block;  # the data block we're working with
my $part;   # the data block part we're working with

# read things and decide what to do
for (<DATA>) {
    chomp;

    # start of a new data block, first part: main
    when (/CELL\s*=\s*"?([^"]+)"?/) {
        $part   = 'main';
        $block  = {
            $part   => {CELL => $1},
            tech    => {},
            spec    => {},
        };
        push @blocks, $block;
        next;
    }

    # start a new part
    when (/\*\*(tech|spec)\*\*/) {
        $part = $1;
        next;
    }

    # fill parts
    when (/"?(\w+)"?\s+"?([^"]+)"?/) {
        $block->{$part}{$1} = $2;
        next;
    }
}

# prepare output
my %columns = (
    main => [
        {name => 'CELL',        length =>  5},
        {name => 'model',       length =>  5},
        {name => 'description', length => 30},
    ],
    tech => [
        {name => 'size',        length => 20},
        {name => 'termOrder',   length => 10},
        {name => 'namePrefix',  length => 10},
        {name => 'prop',        length => 20},
    ],
    spec => [
        {name => 'term',        length => 30},
        {name => 'termOrder',   length => 10},
    ],
);

# part legend
foreach my $part (qw(main tech spec)) {
    my $width = sum map {$_->{length} + 2} @{$columns{$part}};
    print $part . ' ' x ($width - length $part);
}
print "\n";

# column legend
foreach my $part (qw(main tech spec)) {
    foreach my $column (@{$columns{$part}}) {
        my ($name, $length) = @{$column}{qw(name length)};
        print $name . ' ' x ($length - length($name) + 2);
    }
}
print "\n";

# print each block in columns
foreach my $block (@blocks) {
    foreach my $part (qw(main tech spec)) {
        foreach my $column (@{$columns{$part}}) {
            my $value = $block->{$part}{$column->{name}};
            print $value . ' ' x ($column->{length} - length($value) + 2);
        }
    }
    print "\n";
}

__DATA__
CELL    = "abc"
        "model"         "abc"
        "description"   "qwerty+keypad with slide"
**tech**
        size    (big \$l \$w m)
        termOrder         (x y z)
        namePrefix        "S"
        prop       (nil \$l l \$w w)
    **spec**
        term      (nil C \:1 B \:2 E \:3)
        termOrder         (x y z)
***********************************************************
 CELL    = "efg"
        "model"        "efg"
        "description"  "touchscreen+qwerty no slide"
**tech**
        size    (small \$l \$w m)
        termOrder         (x y z)
        namePrefix        "S"
        prop       (nil \$l l \$w w)
 **spec**
        term          (nil x \:1 y \:2 z \:3)
        termOrder         (x y z)

出力

main                                          tech                                                                spec                                        
CELL   model  description                     size                  termOrder   namePrefix  prop                  term                            termOrder   
abc    abc    qwerty+keypad with slide        (big \$l \$w m)       (x y z)     S           (nil \$l l \$w w)     (nil C \:1 B \:2 E \:3)         (x y z)     
efg    efg    touchscreen+qwerty no slide     (small \$l \$w m)     (x y z)     S           (nil \$l l \$w w)     (nil x \:1 y \:2 z \:3)         (x y z)     
于 2012-09-20T14:26:42.407 に答える