2

F1.txt

tom
x
a=1 b=2 c=3 d=4 e=5 
y
b=11 r=12
bob

a=6 b=7 c=8 e=10

结果

F2.txt

.            X         Y
name  a  b  c  d  e  b   r

tom   1  2  3  4  5  11  12

bob   6  7  8  -  10 -   -

你能帮我解决我的这个问题吗?我有一个文件 F1.txt。我的工作是将该文件转换为示例 F2.txt 中所示的格式。我尝试通过删除 Tom 和 Bob 之后的所有字符串值来执行此操作,但 F1.txt 中的数值除外,然后进行连接。这是代码:

use strict;

open (file100,"< data.txt");
open (file101,">>F3.txt");

my @array = < file100>;

print file101 "name    a    b      c      d     e\n\n";
print file101 "tom @array[1]\n\n";
print file101 "bob @array[3]\n\n";

这里data.txt:

tom

1 2 3 4 5

bob 

6 7 8 10

我用这段代码得到的输出是:

F3.txt

name  a  b  c  d  e

tom   1  2  3  4  5

bob   6  7  8  10

预期的输出应该像 F2.txt 中显示的那样,但不像 F3.txt

4

3 回答 3

4
#!/usr/bin/env perl

my $pr = "%-12s";
my @headers = qw/name a b c d e/;
my %names;
while (<DATA>) {
    chomp;
    s/^\s+//g;
    s/\s+$//g;
    my $line = <DATA>;
    $line =~ s/^\s+//g;
    $line =~ s/\s+$//g;
    %{$names{$_}} = split /\s*=\s*|\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;
}

__DATA__
 tom
 a = 10.1 b = 2 c = 300.89 d=4145 e=55
bobby
 a= 60 b = 74.2 c = 8 e = 10.25

输出:

name    a       b       c       d       e       
tom     1       2       3       4       5       
bob     6       7       8       -       10      
于 2012-08-08T02:17:18.017 回答
3

这将满足您的要求

use strict;
use warnings;

my %data;
my @names;

while (<DATA>) {
  next unless /\S/;
  if (/=/) {
    %{ $data{$names[-1]} } = /[^\s=]+/g;
  }
  else {
    push @names, /(\S+)/;
  }
}

my %keys = map %$_, values %data;
my @keys = sort keys %keys;

printf "%-6s %s\n\n", 'name', join '  ', @keys;
printf "%-6s %s\n\n", $_, join '  ', map $_ // '-', @{$data{$_}}{@keys} for @names;

__DATA__
tom

a=1 b=2 c=3 d=4 e=5

bob

a=6 b=7 c=8 e=10

输出

name   a  b  c  d  e

tom    1  2  3  4  5

bob    6  7  8  -  10

更新

对于旧版本(v5.10 之前),Perl 会将定义或运算符//视为放错位置的正则表达式匹配。对于这些平台,第二个printf语句可以这样写

printf "%-6s %s\n\n", $_, join '  ', map { defined $_ ? $_ : '-' } @{$data{$_}}{@keys} for @names;
于 2012-08-08T03:31:43.090 回答
1

为了您的理解,我对此采取了长期措施:

use strict;
use warnings;

my %hash;
my @vals;
my $key;
my $val;
my $name;
my @headings;
my $file100;

open ($file100, "<", "data.txt");


while (<$file100>)
{
        chomp;
        next if (! m/\S/);
        if (m/=/)
        {
            @vals = $_ =~  /(.+)=(.+)\b/g;
            while (@vals)
            {
                $key = shift @vals;
                if (!grep(/^$key$/, @headings))
                {
                    push (@headings, $key);
                }

                $val = shift @vals;
                $hash{$name}{$key} = $val;
            }
        } else {
           $name = $_;
}

print "name\t" . join ("\t", @headings) . "\n\n";
for my $key1 (keys %hash)
{
    print $key1;
    for (@headings)
    {
        if (defined $hash{$key1}{$_})
        {
            print "\t" . $hash{$key1}{$_};
        } else
        {
            print "\t-";
        }
    }
    print "\n\n";
}

你需要拿起一本 Perl 书并学习它。

于 2012-08-08T02:29:40.663 回答