Как я могу получить длину самого длинного значения в столбце CSV?

#csv #perl

Вопрос:

Я новичок в Perl. Я застрял в форматировании и отображении данных. Мне нужно прочитать данные из CSV-файла и распечатать их на экране в правильном формате. Ширина каждого столбца определяется максимальной длиной элемента, присутствующего в столбце.

 my $file = $ARGV[0] or die; 
open(my $data, '<', $file) or die; 
my $max = 0;

while (my $line = <$data>)  
{ 
    chomp $line; 


# Split the line and store it 
# inside the words array 
my @words = split ", ", $line;   
my @C = split( ",", $line);
#$max = length $C[1];
print ("c", "$C[2]n");
for (my $i = 0; $i <= 2; $i  ) 
{ 
    #print "$words[$i] "; 
} 
#print "n"; 


} 



 print "maximum:max($max)n";
 

Комментарии:

1. Можете ли вы показать образец входных данных и соответствующий ожидаемый результат?

2. если у вас в столбце есть различные элементы, такие как {яблоко, летучая мышь, кошка, танцы}, теперь ширина всего элемента должна быть равна длине танца, чтобы он выглядел правильно на терминале.

3. Пожалуйста, обновите вопрос образцами.

Ответ №1:

Программа столбца может сделать это (см. https://unix.stackexchange.com/q/18861/12567):

 $ column -t -s, input.csv
cat            wooly mammoth  lizard
kangaroo       dog            bird
grey squirrel  koala          sea otter
 

Если вы хотите сделать это сами, вам нужно увидеть все ценности.

Проще всего было бы сделать два прохода. В первом проходе вы получите максимальную длину каждого столбца и сохраните ее @longest . Если следующая строка содержит более длинное значение в столбце, вы заменяете это значение в @longest . В конце самая длинная длина для каждого столбца находится в @longest :

 open my $fh, '<', 'input.csv' or die ...;

my $csv = Text::CSV_XS->new;

@longest;
while( my $row = $csv->getline( $fh ) ) {
    foreach my $i ( 0 .. $#$row ) {
        my $length = length $row->[$i];
        $longest[$i] = $length if $longest[$i] < $length;
        }
    }
 

После того, как вы это сделаете, вы снова пройдете по линиям и используете эти ширины:

 seek $fh, 0, 0; # back to beginning of file
my $template = join ' ', map "%-${_}s", @longest;
print "format: $templaten";

while( my $row = $csv->getline( $fh ) ) {
    printf "$templaten", @$row;
    }