以下代码段对版本号进行排序。我在脚本中测试它似乎是正确的。
sort {
my @left = split( /\./, $a );
my @right = split( /\./, $b );
if ( $left[0] <=> $right[0] ) {
return $left[0] <=> $right[0];
}
if ( $left[1] <=> $right[1] ) {
return $left[1] <=> $right[1]
}
elsif ( @left < @right ) {
return -1;
}
return @left < @right ? -1 : 1;
} @versions
如何使这个更简洁/更简洁,并在管道序列中运行它
即numbers_generator | perl -e SORT_HERE | other_command
答案 0 :(得分:5)
使用标准version module可以更轻松,更可靠地完成此操作。
sort { version->parse($a) <=> version->parse($b) } @versions
至于管道,取决于接收到的是什么。您可以将它们作为命令行参数(即@ARGV
)或作为stdin的行接受。您可以分开输出空格,也可以分开输出。
这里它将版本作为stdin上的行并输出为单独的行。
#!/usr/bin/env perl
use strict;
use warnings;
use v5.10;
use version;
say join "\n",
sort {
version->parse($a) <=> version->parse($b)
}
map { chomp; $_ }
<STDIN>;
它会像这样使用。
$ echo -e '19.0\n2.9\n0.1.23.45' | sort_versions
0.1.23.45
2.9
19.0
然后另一端逐行读取STDIN的版本。
但是如果你有GNU排序,你应该使用sort -V
作为Benjamin W. suggested。
答案 1 :(得分:2)
比较数组的长度毫无意义。
比较第一对,如果第一对相等,第二对相同,第三对相同,应该足够了:
return $left[0] <=> $right[0]
|| $left[1] <=> $right[1]
|| $left[2] <=> $right[2]
您需要禁用警告,以便在比较不同长度的两个版本时不会获得“使用未初始化的值”。
因此,管道看起来像
numbers_generator \
| perl -e 'print sort { @l = split /\./, $a; @r = split /\./, $b; $l[0] <=> $r[0] || $l[1] <=> $r[1] || $l[2] <=> $r[2] } <>' \
| other_command
答案 2 :(得分:1)
numbers_generator |
perl -Mversion -le'
chomp( @a = <> );
print for sort { version->parse($a) cmp version->parse($b) } @a;
' |
other_command
答案 3 :(得分:0)
您不一定需要在这里使用Perl。您可以使用sort
,将.
指定为字段分隔符,然后按字母n
对每个字段进行排序
numbers_generator | sort -t. -k 1,1n -k 2,2n -k 3,3n | other_command
请注意,这是最多 3位版本号。
修改:到