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中显示的对齐输出? 当我使用与我给出的输入相似的实际数据时,我无法实现我的预期。
编辑:示例输入已与预期结果一起更改
答案 0 :(得分: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
。
对于最大长度的动态检测,这需要另一个问题:)
答案 1 :(得分: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
答案 2 :(得分:0)
使用sprintf填充对齐输出的任何字符串的简单方法。 例如:您希望2个色谱柱的均匀尺寸为20个字符,并带有分离器。您还希望在指定的文本后左对齐并填充右列。没有问题:
print sprintf("# %20s | %-20s #","Column1","Column2")."\n";
会打印:
username@hostname:~$ perl -e 'print sprintf("# %20s | %-20s #","Column1","Column2")."\n";'
# Column1 | Column2 #