Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 如何";pad";具有对齐的最后一列的可变长度字符串_Perl - Fatal编程技术网

Perl 如何";pad";具有对齐的最后一列的可变长度字符串

Perl 如何";pad";具有对齐的最后一列的可变长度字符串,perl,Perl,我有以下格式的输入: 我能够使用regex/(\S+)\S+(\S+)\S+(\S+)\S+(\S+)\S+/轻松提取这些单独字段。我给它们命名为$time,$name,和$number。我的问题是我想显示它,以便$number完全对齐。由于$name可以是任意长度,因此最好的解决方案是什么 我希望输出像这样。请注意,我必须使用点来对齐最后一个字段,因为我无法使用空格键来进行对齐,不知道为什么。随便 我考虑将$name放入一个数组中。然后使用函数查找字符计数最长的字符。最后,我将填充较短

我有以下格式的输入:



我能够使用regex
/(\S+)\S+(\S+)\S+(\S+)\S+(\S+)\S+/
轻松提取这些单独字段。我给它们命名为
$time
$name
,和
$number
。我的问题是我想显示它,以便
$number
完全对齐。由于
$name
可以是任意长度,因此最好的解决方案是什么

我希望输出像这样。请注意,我必须使用点来对齐最后一个字段,因为我无法使用空格键来进行对齐,不知道为什么。随便



我考虑将
$name
放入一个数组中。然后使用函数查找字符计数最长的字符。最后,我将填充较短的名称以匹配最长的名称。有没有更好、更有效的方法可以做到这一点?

这是某人给出的:

my($name,$telephone,$stime);
格式信息=

@ 要设置格式,请尝试使用函数,如中所示

$line = sprintf "%-12s %-20s %-s\n", $time, $name, $number;

(减号表示左对齐)

无论你做什么,你都需要做两次传递-一次查找长度,一次打印,在格式中使用该长度。我个人会使用sprintf已经给出的格式问题的答案,只是改变其中的数字


确切地说,如何进行这两次传递取决于数据来自何处——如果文件很大,则读取两次文件可能比将其预处理到内存中更明智,但您提出的数组解决方案听起来不错。

如果您不知道中间字段的最大宽度,您必须在数据上进行两次传递

#/usr/bin/perl
严格使用;
使用警告;
使用Fcntl qw(:seek);
我的$max_长度=0;
my$data\u pos=告诉数据;
while(我的$line=){
最后,除非$line=~/\S/;
我的$name=(拆分“”,$line)[1];
我的$name\u length=长度$name;
$max\u length=$name\u length,如果$name\u length>$max\u length;
}
搜索数据,$DATA\U pos,搜索集;
while(我的$line=){
最后,除非$line=~/\S/;
我的($date,$name,$ip)=拆分“”,$line;
printf“%s%-${max_length}s%s\n”、$date、$name、$ip;
}
__资料__
09:08:11 XXXXXXXXXXXX 1.1.1.1
09:09:03 YYYY 2.2.2.2
09:12:37 ZZZZ 3.3.3.3
看一看

这是建议使用的方法。请参阅前面的回答:

下面是Perl6::Form处理数据的示例:

use Perl6::Form;

my ($time, $name, $number);

my @data = (
    [ qw(09:08:11 XXXXXXXXXXXXX 1.1.1.1) ],
    [ qw(09:09:03 YYYYYYYY 2.2.2.2)      ],
    [ qw(09:12:37 ZZZZ 3.3.3.3)          ],
);

for my $line (@data) {
    push @$time,   $line->[0];
    push @$name,   $line->[1];
    push @$number, $line->[2];
}

print form
    '{[[[[[[}    {[[[[[[[[[[[[[[[[[[[[}    {[[[[[[}',
    $time,       $name,                    $number;

注意。如果您的数据字段比指定的表单字段大,那么您将遇到格式问题(同样的问题也适用于sprintf和格式解决方案)

根据您的输出要求,很容易修复。例如,如果您想保持表格的稳定性,那么

print form { layout => 'tabular' },
    '{[[[[[[}    {[[[[[[[[[[[[[[[[[[[[}    {[[[[[[}',
    $time,       $name,                    $number;
…将word为您包装每一列

      $lineLength = length($line1);
      write;
}
close FD1;

format STDOUT =
@>>>>> @*
$lineLength,$line1
.
;

因此,在上面的示例中,“$lineLength”被向右推,并带有前导空格。

使用“代码格式”选项指定应使用固定宽度字体和预格式化。:)我刚刚在手机上编辑了一下,直到我意识到这太难了。每个数字都是一位数吗?如果没有,你想做什么?谢谢你的编辑。很高兴知道我可以在代码选项中添加空格。
#!/usr/bin/perl

use strict;
use warnings;

use Fcntl qw( :seek );

my $max_length = 0;
my $data_pos = tell DATA;

while ( my $line = <DATA> ) {
    last unless $line =~ /\S/;
    my $name = (split ' ', $line)[1];
    my $name_length = length $name;
    $max_length = $name_length if $name_length > $max_length;
}

seek DATA, $data_pos, SEEK_SET;

while ( my $line = <DATA> ) {
    last unless $line =~ /\S/;
    my ($date, $name, $ip) = split ' ', $line;
    printf "%s %-${max_length}s %s\n", $date, $name, $ip;
}

__DATA__
09:08:11        XXXXXXXXXXXXX  1.1.1.1
09:09:03        YYYYYYYY  2.2.2.2
09:12:37        ZZZZ   3.3.3.3
use Perl6::Form;

my ($time, $name, $number);

my @data = (
    [ qw(09:08:11 XXXXXXXXXXXXX 1.1.1.1) ],
    [ qw(09:09:03 YYYYYYYY 2.2.2.2)      ],
    [ qw(09:12:37 ZZZZ 3.3.3.3)          ],
);

for my $line (@data) {
    push @$time,   $line->[0];
    push @$name,   $line->[1];
    push @$number, $line->[2];
}

print form
    '{[[[[[[}    {[[[[[[[[[[[[[[[[[[[[}    {[[[[[[}',
    $time,       $name,                    $number;
print form { layout => 'tabular' },
    '{[[[[[[}    {[[[[[[[[[[[[[[[[[[[[}    {[[[[[[}',
    $time,       $name,                    $number;
      $lineLength = length($line1);
      write;
}
close FD1;

format STDOUT =
@>>>>> @*
$lineLength,$line1
.
;