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

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

あなたの並べ替えはうまくいきます。唯一の問題は、配列に要素が 1 つしかないことです。ソートのすぐ上で、割り当てを行います。

これを機能させたい場合は、並べ替える前に配列を埋める必要があります。

これもワンライナーです:

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

「Eskimo Kiss」演算子の使用に注意してください}{END { ... }ブロックと同様に機能し、その後に続くものはすべて入力の最後に実行されます。

興味深いことに、「Eskimo Kiss」が機能するのは、スイッチがプログラム文字列の周りに非常に文字通りの方法でループを-n追加するためです。デパースすると、わかりやすくするためにコメントを付けて、次のようになります。while(<>) { ... }-e

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 に答える