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 に示すような形式に変換することです。F1.txt の数値を除いて、Tom と Bob の後のすべての文字列値を削除してから、連結してみました。コードは次のとおりです。

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 は defined-or 演算子//を誤った正規表現の一致として認識します。これらのプラットフォームでは、2 番目の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 に答える