0

我不确定为什么这种 Perl 排序不起作用。请建议如何解决这个问题。

while (<>) {

    chomp;
    if (/VIOLATE/) {

        @lines = split " ", $_;
        #print "$lines[-2]\n";  ## Print last but one column
        my @viol = "$lines[-2]\n";

        @sorted = sort {$a <=> $b} @viol;
        print "@sorted";
    }
};

命令 :perl test.pl test.log

测试日志:

0.98           2.04          -1.106  VIOLATE
0.98           2.04          3.06
0.98           2.04          -11.06  VIOLATE
0.98           2.04          -1.06  VIOLATE
0.98           2.04          1.06 
0.98           2.04          -0.226  VIOLATE
0.98           2.04          -2.06  VIOLATE
4

2 回答 2

6

您是否尝试匹配其中的任何行VIOLATE,将结果放入数组中,然后对所有违规行为进行排序?如果是这样,您需要@viol在循环外声明和排序:

use strict;
use warnings; # Don't forget these!

my @viol;

while (<>) {
    chomp;
    if (/VIOLATE/) {
        my @lines = split(/\s+/); # Split on one or more whitespace characters.
        push @viol, $lines[-2];
    }
}

# sort and print
my @sorted = sort {$a <=> $b} @viol;
print "@sorted";

这输出:-11.06 -2.06 -1.106 -1.06 -0.226

于 2012-10-23T08:04:01.203 回答
4

你的排序工作得很好。唯一的问题是您的数组只有一个元素。在排序的正上方,你做作业。

如果你想让它工作,你需要在排序之前填充你的数组。

这也是单行:

perl -lanwe 'push(@a, $F[-2]) if /VIOLATE/ }{ print for sort { $a <=> $b } @a' 

请注意“爱斯基摩之吻”运算符的使用,}{. 它的工作方式类似于END { ... }块,因为它在输入结束时执行之后的任何内容。

对于好奇的人: “爱斯基摩之吻”之所以有效,是因为该开关以一种非常直接的方式在程序字符串周围-n添加了一个while(<>) { ... }循环。-eDeparsed,它看起来像这样,为了清晰起见,注释:

perl -MO=Deparse -lanwe 'push(@a, $F[-2]) if /VIOLATE/ }{ print for sort { $a <=> $b } @a'
BEGIN { $^W = 1; }                     # warnings enabled by -w
BEGIN { $/ = "\n"; $\ = "\n"; }        # line endings enabled by -l
LINE: while (defined($_ = <ARGV>)) {   # while(<>) loop added by -n
    chomp $_;                          # chomp added by -l
    our(@F) = split(' ', $_, 0);       # autosplit enabled by -a
    push @a, $F[-2] if /VIOLATE/;      # our code
}                                      # eskimo kiss close
{                                      # eskimo kiss open
    print $_ foreach (sort {$a <=> $b} @a);   # our END code
}                                      # closing bracket added by -n
-e syntax OK
于 2012-10-23T08:13:13.993 回答