【问题标题】:Perl: How to check the max width of word present in columns of array after reading from file?Perl:从文件读取后如何检查数组列中单词的最大宽度?
【发布时间】:2021-01-16 19:36:22
【问题描述】:

我正在读取一个文件并再次写入另一个文件。因此,在编写时,由于后续列的一些大字对齐会失真。我想对齐所有列,无论它们的长度如何。我在这里得到了一个related question。但问题是他们正在使用 Perl 模块Perl6::Form,而我想不使用任何模块。

#This the input file
Hey! How Are You
I   AM  FINEEE Thankyouuu
1   22   333   4444

对齐后应该是这样的:

Hey!  How   Are     You
I     AM    FINEEE  Thankyouuu
1     22    333     4444

已尝试的代码(已更新):

#!usr/bin/perl
use warnings;
use strict;
use feature 'say';
$file1 = "file1.log";
$temp = "temp.log";
open(OUT, "<$file1") or die "Could not open file $file1: $!";
open(temp,"+>>$temp") or die "Could not open file $temp: $!";

while (my $line = <OUT>) {
    my @fs = split " ", $line;   
     
my @rows = @fs ;
 

@col_lens =  map { length } @rows if $.==1;

   for my $col_idx (0..$#rows) {
      my $col_len = length $rows[$col_idx];
      if ($col_lens[$col_idx] < $col_len) {                  
         $col_lens[$col_idx] = $col_len;               #line 144
      }
   }
   
     
     say temp1 (join "|",@fs);
 }
 
    close temp1;
    close OUT;

更新:代码正在运行,并给出了最大单词的长度,但也收到了一些警告。但是现在我将如何根据其中的最大单词大小为每列添加空格? say temp1 (join "|",@fs); 这个只加“|”在他们之间。

Use of uninitialized value in numeric lt (<) at log.pl line 144,
Use of uninitialized value in numeric lt (<) at log.pl line 144,
Use of uninitialized value in numeric lt (<) at log.pl line 144,
Use of uninitialized value in numeric lt (<) at log.pl line 144,
Use of uninitialized value in numeric lt (<) at log.pl line 144,
Use of uninitialized value in numeric lt (<) at log.pl line 144,

【问题讨论】:

  • 你为什么不使用标签?它们不会在文本编辑器中对齐文本,但它们会使其机器可读并可由 Excel 打开。
  • 如果不局限于perl,可以考虑使用column -t &lt;input_file&gt;
  • @AlexanderMashin,是的,使用 tab 然后生成一个 tab limited xls 是不错的选择。但是我再次生成了日志格式,所以这就是需要对齐的原因。
  • my @col_lens = map { length } @rows; 应该为您提供当前行列长度。查找每列的最大值,查找文件的开头,然后 printf() 使用最大列宽输出文件。
  • @Сухой27 ,你能检查更新的部分吗?谢谢。

标签: string perl output alignment multiple-columns


【解决方案1】:

也许以下类型的东西应该可以完成这项工作

use strict;
use warnings;
use feature 'say';

my @lines;
my @max_len;

while( <> ) {
    next if /^#/;
    chomp;
    my @data = split;
    push @lines, \@data;
    my @length = map { length } @data;
    @max_len = map { $max_len[$_] || $length[$_] } 0..$#length;
    @max_len = map { $max_len[$_] < $length[$_] ? $length[$_] : $max_len[$_] } 0..$#length;
}

my @formats = map { '%-'. $_ . 's' } @max_len;
my $format  = join ' ', @formats, "\n";

printf $format, @{$_} for @lines;

script.pl file1.log 运行产生以下输出

Hey! How Are    You
I    AM  FINEEE Thankyouuu
1    22  333    4444

注意:输出可以重定向到输出文件script.pl file1.log &gt; temp.log

【讨论】:

    【解决方案2】:

    把它放在文件program.pl中

    #!/usr/bin/perl
    use warnings; use strict; my(@table,@len);
    while(<>){
        my @row = split /\s+/;
        for my $col ( 0 .. $#row ){
            my $l = length($row[$col]);
            $len[$col] = $l if not defined$len[$col] or $l > $len[$col];
        }
        push @table, \@row;
    }
    my $format = join "  ", map '%-'.$_.'s', @len;
    printf "$format\n", @$_ for @table;
    

    ...然后运行:

    perl program.pl inputfile.txt > outputfile.txt
    

    或许

    chmod +x program.pl
    cat inputfile.txt | ./program.pl > outputfile.txt
    

    【讨论】:

      【解决方案3】:

      不要重新发明轮子。 *NIX 实用程序 column 可以很好地处理此任务(另请参阅 Light 的评论)。

      例子:

      在空格(制表符、空格等)上拆分输入:

      perl -le 'print join "\t", qw(Hey! How Are You); print join "\t", qw(I AM FINEEE Thankyouuu ), q{John Doe};' | \
        column -t 
      Hey!  How  Are     You
      I     AM   FINEEE  Thankyouuu  John  Doe
      

      这里,John Doe 被视为 2 个字段。


      在选项卡上拆分输入(将带有空格的字段视为单个字段):

      perl -le 'print join "\t", qw(Hey! How Are You); print join "\t", qw(I AM FINEEE Thankyouuu ), q{John Doe};' | \
        column -t -s$'\t'
      Hey!  How  Are     You
      I     AM   FINEEE  Thankyouuu  John Doe
      

      这里,John Doe 被视为 1 个字段。

      【讨论】:

        猜你喜欢
        • 2019-04-24
        • 1970-01-01
        • 2011-08-27
        • 1970-01-01
        • 2021-08-27
        • 1970-01-01
        • 1970-01-01
        • 2012-09-12
        • 2013-01-26
        相关资源
        最近更新 更多