-1
Test.txt
tom 
cat=0  bat=1  mat=0  pen=1
ironman122_bore.1 
cat=8e-7  bat=8.001e-7  mat=5e-6  pen=200.001e-6     
batmanbegin_nice.1  
cat=10  bat=1  mat=0.25  pen=49.25   

ここに私の入力のサンプルがあり、私の出力は Out.txt のようになると思います

Out.txt
name                cat       bat       mat       pen               
tom                 -         1         -         -    
ironman122_bore.1   8e-7      8.001e-7  5e-6      200.001e-6
batmanbegin_nice.1  10        1         0.25      49.25 

これが私が試したものです

my $pr = "%-12s"; 
my @headers = qw/name cat bat mat pen/; 
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; 
}

しかし、私は次のように出力を取得します

name          cat       bat       mat       pen               
tom        -         1         -         -    
ironman122_bore.1  8e-7      8.001e-7  5e-6      200.001e-6
batmanbegin_nice.1  10         1         0.25     49.25 

Out.txt に示されているように、整列された出力を取得するようにコードを変更するにはどうすればよいですか? 入力として与えたものと似た実際のデータを使用したときに、期待したことを達成できませんでした。

編集:サンプル入力は、期待される結果とともに変更されました

4

3 に答える 3

0

整列された出力のために任意の文字列を埋める簡単な方法は、sprintfを使用することです。例:セパレーターを使用して、2列を20文字で均等なサイズにする必要があります。また、右の列を左揃えにして、指定したテキストの後にパディングする必要があります。問題なし:

print sprintf("# %20s | %-20s #","Column1","Column2")."\n";

印刷します:

username@hostname:~$ perl -e 'print sprintf("# %20s | %-20s #","Column1","Column2")."\n";'
#              Column1 | Column2              #
于 2012-08-15T08:07:49.900 に答える
0

以前のデータで

投稿されたコードは私にとってはうまくいきます。

出力

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

表示しているフォントは固定幅ですか?


新しいデータで

ずれの理由は、'name' 列の下の項目の一部が 12 文字を超えているためです (たとえば、'batmanbegin_nice.1' は 18 文字です)。

(s)printf元の投稿で指定されているように、文字列を 12 文字に切り捨てません。

切り捨てるには、 と の間に を指定し.ます。%12

printf '%.12s', 'batmanbegin_nice.1' ;  # "batmanbegin_"

切り捨てが望ましくない場合は、文字列の長さを に増やします%20s

最大長の動的検出に関しては、別の質問が必要です:)

于 2012-08-15T07:52:16.727 に答える
0
#!/usr/bin/env perl

use strict;
use warnings;
use List::MoreUtils qw(uniq);

my $pr = "%-24s";
my @headers = qw/name/;
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;
}
push @headers, uniq sort map { keys %{$names{$_}}; } keys %names;
printf $pr x @headers . "\n", @headers;
for (keys %names) {
    my @ds = ($_);
    for my $k (@headers[1..$#headers]) {
        my $v = $names{$_}->{$k};
        push @ds, defined $v ? $v : '-';
    }
    printf $pr x @ds . "\n", @ds;
}

__DATA__
 tom
cat = 0  bat =1  mat= 0  pen=1
ironman122_core.1
 cat= 8e-7  bat= 8.001e-7  mat= 5e-6  pen= 200.001e-6
batmanbegin_core.1
cat=10  bat = 1  mat= 0.25  pen= 49.25

出力:

name                    bat                     cat                     mat                     pen                     
tom                     1                       0                       0                       1                       
batmanbegin_core.1      1                       10                      0.25                    49.25                   
ironman122_core.1       8.001e-7                8e-7                    5e-6                    200.001e-6  
于 2012-08-15T08:04:08.573 に答える