如何在Perl中拆分固定宽度的列?

scr*_*613 10 perl

编程对我来说是如此新鲜,我为不知道如何表达问题而道歉.

我有一个Perl脚本从内部工具获取变量.这并不总是它看起来像,但它将始终遵循这种模式:

darren.local           1987    A      Sentence1
darren.local           1996    C      Sentence2
darren.local           1991    E      Sentence3
darren.local           1954    G      Sentence4
darren.local           1998    H      Sentence5
Run Code Online (Sandbox Code Playgroud)

使用Perl,将每条线路变为变量的最简单方法是什么?根据内部工具吐出的内容,每条线总是不同的,并且可以有超过五条线.每行中的大写字母最终将被排序(所有As,所有C,所有Es等).我应该看正则表达式吗?

bri*_*foy 19

我喜欢使用unpack进行此类操作.它快速,灵活,可逆.

您只需知道每列的位置,并unpack可以自动修剪每列的额外空格.

如果您在其中一个列中更改某些内容,则可以通过使用相同格式重新打包来轻松打包到原始格式:

my $format = 'A23 A8 A7 A*';

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

    my( $machine, $year, $letter, $sentence ) =
        unpack( $format, $_ );

    # save the original line too, which might be useful later
    push @grades, [ $machine, $year, $letter, $sentence, $_ ];
    }

my @sorted = sort { $a->[2] cmp $b->[2] } @grades;

foreach my $tuple ( @sorted ) {
    print $tuple->[-1];
    }

# go the other way, especially if you changed things
foreach my $tuple ( @sorted ) {
    print pack( $format, @$tuple[0..3] ), "\n";
    }

__END__
darren.local           1987    A      Sentence1
darren.local           1996    C      Sentence2
darren.local           1991    E      Sentence3
darren.local           1954    G      Sentence4
darren.local           1998    H      Sentence5
Run Code Online (Sandbox Code Playgroud)

现在,还有一个额外的考虑因素.听起来你可能在一个变量中有这么大的多行文本.通过在标量引用上打开文件句柄来处理文件.文件句柄的东西负责其余的事情:

 my $lines = '...multiline string...';

 open my($fh), '<', \ $lines;

 while( <$fh> ) {
      ... same as before ...
      }
Run Code Online (Sandbox Code Playgroud)

  • 可读Perl的一个很好的例子......(即使是每两年一次的用户) (3认同)
  • +1良好的插图`unpack`,一个经常被忽视的工具.非常细微的细节:如果需要完美的可逆性,你想使用`a*`而不是'A*`.后者将删除尾随空格,这可能是不合需要的(例如,如果句子的长度不同,但数据的用户不希望在反向行程中出现锯齿状记录). (3认同)