Как “заполнить” строку переменной длины, чтобы иметь выровненный последний столбец

11
задан nrz 22 November 2014 в 07:40
поделиться

5 ответов

For formatting, try using the sprintf function, as in

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

(the minus sign means left-justify)

21
ответ дан 3 December 2019 в 02:52
поделиться

Это было дано кем-то здесь :

my($name, $telephone, $stime);

format Infos =
@<<<<<<<<<<<<<<<<<<@<<<<<<<<<<<<<<<<<<<@<<<<<<<<<<<<<<<
$name,             $telephone,         $stime
.

$~ = 'Infos';

($name, $telephone, $stime) = ('Name:', 'Telephone:', 'Start Time:');
write;

($name, $telephone, $stime) = ('Mike Bax', 'tel-41596', 'Fri 8/22 13:31');
write;

Вы можете изменить имена переменных, и это должно сработать для вас.

4
ответ дан 3 December 2019 в 02:52
поделиться

If you do not know the maximum width of the middle field, you will have to make two passes over the data as @ijw notes.

#!/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
2
ответ дан 3 December 2019 в 02:52
поделиться

Whatever you do, you're going to have to do with two passes - one to find the length, one to print, using that length in the formatting. I would go with the sprintf answer already given for the formatting, personally, just varying the number in it.

Exactly how you do the two passes rather depends on where the data is coming from - reading a file twice might be wiser than preprocessing it into memory if the file is huge, but the array solution you're proposing sounds good to me.

0
ответ дан 3 December 2019 в 02:52
поделиться

Взгляните на Perl6 :: Form .

Это рекомендуемый подход вместо использования формата . См. Предыдущий ответ о переполнении стека: Какие еще языки имеют функции и / или библиотеки, похожие на формат Perl?

Вот пример 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;


NB. Если ваши поля данных когда-либо станут больше, чем указанные поля формы, вы столкнетесь с проблемами форматирования (и то же самое относится к sprintf и решениям форматирования).

Это легко исправить в зависимости от ваших требований к выходным данным. Например, если вы хотите сохранить стабильность таблицы, то ...

print form { layout => 'tabular' },
    '{[[[[[[}    {[[[[[[[[[[[[[[[[[[[[}    {[[[[[[}',
    $time,       $name,                    $number;

... будет переносить слова в каждый столбец.

3
ответ дан 3 December 2019 в 02:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: