我的输入格式如下,我想为这些数据创建一个表格格式。
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;
}
这不会产生必要的结果,所以请帮助我解决这个问题。
答案 0 :(得分:3)
这真的不是最简单的任务,而且总是如此,有多种方法可以做到这一点。这是一个。如果有任何问题,请随意提问,因为解释所有内容的代码实在太多了。
然而,如果这是我的任务,我会选择HTML作为输出格式来摆脱所有这些宽度计算 - 也有舒适的JS工具来排序这些表。如果你真的想用文字做这样的事情,也许“好老formats”适合你。 ;)
#!/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)